I’m trying to insert an entry into my database with a one-to-one relationship to another entity. I’m using spring data jpa and postgres.
My code looks as follows:
@MappedSuperclass
@Getter
@Setter
@ToString
public abstract class Post {
@Id
@GeneratedValue
private Long id;
private Long botId;
private String description;
private boolean hasBeenUsed;
@Column(length = 1000)
private String imageUrl;
@CreationTimestamp
@Column(nullable = false, updatable = false)
private LocalDateTime createdAt;
}
@Entity
@Getter
@Setter
@ToString
public class PollPost extends Post {
@OneToOne(cascade = CascadeType.ALL)
private PollPostImageTextData pollImageTextData;
}
@Entity
@Getter
@Setter
@ToString
public class PollPostImageTextData {
@Id
@GeneratedValue
private Long id;
private String question;
private String answerA;
private String answerB;
private String correctAnswer;
}
If I now try to create a PollPost as follows:
protected PollPost createPollPost(long botId) throws IOException {
System.out.println("Generating Poll Post...");
String textData = "{n "question": "sample question?",n "answerA": "sample answerA",n "answerB": "samepleAnswerB",n "correctAnswer": "answerB"n}";
String description = "sample desc";
ObjectMapper mapper = new ObjectMapper();
PollPostImageTextData pollImageTextData = new PollPostImageTextData();
try {
System.out.println("Generating image text data...");
pollImageTextData = mapper.readValue(textData, PollPostImageTextData.class);
System.out.println(pollImageTextData);
} catch (Exception e) {
e.printStackTrace();
}
if (pollImageTextData == null) {
throw new IllegalStateException("Poll Image Text Data must not be null");
}
String imageUrl = "test url";
PollPost post = new PollPost();
post.setPollImageTextData(pollImageTextData);
post.setDescription(description);
post.setHasBeenUsed(false);
post.setBotId(botId);
post.setImageUrl(imageUrl);
System.out.println("Saving PollPost with PollImageTextData ID: " + (pollImageTextData.getId() != null ? pollImageTextData.getId() : "null"));
pollPostRepository.save(post);
return post;
}
I get the error: org.springframework.dao.DataIntegrityViolationException: could not execute statement [ERROR: insert or update on table "poll_post" violates foreign key constraint "fk1db3khk0i1jc6mehnod8fy4r" Detail: Key (poll_image_text_data_id)=(852) is not present in table "poll_image_text_data".
I’m not sure why this occurs, since the @OneToOne(cascade = CascadeType.ALL)
annotation of the PollImageTextData should create the necessary entry in the database. Thanks in advance.
EDIT:
Before using a MappedSuperclass I created posts very similar like the following and it worked without any problems.
@Entity
@Getter
@Setter
@ToString
public class Post {
@Id
@GeneratedValue private Long id;
private long botId;
private String description;
private boolean hasBeenUsed;
@Column(length = 1000)
private String imageUrl;
@OneToOne(cascade = CascadeType.ALL)
private ImageTextData imageTextData;
@CreationTimestamp // This annotation automates the timestamping when the entity is persisted
@Column(nullable = false, updatable = false)
private LocalDateTime createdAt; // Field to store the creation timestamp
}
and
@Entity
@Getter
@Setter
@ToString
public class ImageTextData {
@Id
@GeneratedValue private Long id;
private String question;
private String answerA;
private String answerB;
private String correctAnswer;
}
Post Creation looked like this:
public Post createPost(long botId) throws IOException {
String textData = "{n "question": "sample question?",n "answerA": "sample answerA",n "answerB": "samepleAnswerB",n "correctAnswer": "answerB"n}";
String description = "sample desc";
ObjectMapper mapper = new ObjectMapper();
ImageTextData imageTextData = null;
try {
imageTextData = mapper.readValue(textData, ImageTextData.class);
System.out.println(imageTextData);
} catch (Exception e) {
e.printStackTrace();
}
//String imageUrl = getPostImage(botId);
Post post = new Post();
post.setDescription(imageTextData.getQuestion());
post.setHasBeenUsed(false);
//post.setImageUrl(imageUrl);
post.setBotId(botId);
post.setImageUrl("sample image");
post.setImageTextData(imageTextData);
postRepository.save(post);
return post;
}
I would really like to know why this way worked, but after using inheritance it no longer created the imageTextData implicitly?
2
Answers
The reason why it worked before without inheritance and no longer with inheritance was due to a naming error on my side...
I called the field
pollImageTextData
but it should have beenpollPostImageTextData
. This way Hibernate was not able to map things correctly. A really silly mistake, but in case anyone experiences something similar, double check your namings, especially if they are as long and nested as mine.Thanks a lot to anyone who tried to help!
Easy, you’ve never saved
pollImageTextData
to database, so when you try to savepost
it looks for a row inPollPostImageTextData
table that doesn’t exist.Just create a repository for
PollPostImageTextData
and save thepollImageTextData
before savingpost
.