skip to Main Content

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


  1. Chosen as BEST ANSWER

    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 been pollPostImageTextData. 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!


  2. Easy, you’ve never saved pollImageTextData to database, so when you try to save post it looks for a row in PollPostImageTextData table that doesn’t exist.

    Just create a repository for PollPostImageTextData and save the pollImageTextData before saving post.

    protected PollPost createPollPost(long botId) throws IOException {
    
        System.out.println("Generating Poll Post...");
    
        // create PollPostImageTextData pollImageTextData ...
    
        // save it
        pollPostImageTextDataRepository.save(pollImageTextData);
    
        // create PollPost post ...
    
        pollPostRepository.save(post);
        return post;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search