I would like to save an object of my QuestionCompletion class with all the children. One of these children has a composite primary key. And as part of this primary key, I have a foreign key to another object. As a result, I get this error:
Exception caught during request processing: javax.ejb.EJBTransactionRolledbackException: could not set a field value by reflection setter of com.example.model.domain.QuestionCompletionAnswerPK.questionCompletionId javax.ejb.EJBTransactionRolledbackException: could not set a field value by reflection setter of com.example.model.domain.QuestionCompletionAnswerPK.questionCompletionId
And the last “caused”, of course, is a NullPointerException :
Caused by: java.lang.NullPointerException
This is part of my code. The last line causes an error.
QuestionCompletion questionCompletion = new QuestionCompletion(); List<QuestionCompletionAnswer> answers = new ArrayList<QuestionCompletionAnswer>(); for (;;) { // loop isn't important; it loop for answers ExtendedQuestion extendedQuestion = new ExtendedQuestion(); extendedQuestion.setId(extendedQuestionId); //extendedQuestionId is known to me in that place for (;;) { // loop isn't important; it loop for question answers //questionCompletion and extendedQuestion are popualted here QuestionCompletionAnswer questionCompletionAnswer = new QuestionCompletionAnswer(); questionCompletionAnswer.setQuestionCompletion(questionCompletion); questionCompletionAnswer.setExtendedQuestion(extendedQuestion); answers.add(questionCompletionAnswer); } } questionCompletion.setAnswers(answers); questionCompletionService.saveOrMerge(questionCompletion);
This is my main entity class, which I would like to keep with all its children. I realized that List<QuestionCompletionAnswer> is causing problems. I used cascade = CascadeType.ALL to also save childs elements.
@javax.persistence.Entity @org.hibernate.annotations.Entity(dynamicUpdate = true) @Table(name = "question_completion") public class QuestionCompletion implements Serializable { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "question_completion_gen") @SequenceGenerator(name = "question_completion_gen", sequenceName = "question_completion_id_seq") @Column(name = "question_completion_id") private Long id; @OneToMany(cascade = CascadeType.ALL) @JoinColumn(name = "extended_question_id") protected List<QuestionCompletionAnswer> answers; }
This is my class - the primary key for the QuestionCompletionAnswer class.
@Embeddable public class QuestionCompletionAnswerPK implements Serializable { @Column(name = "question_completion_id") protected Long questionCompletionId; @Column(name = "extended_question_id") protected Long extendedQuestionId; }
And this is the class that uses my EmbeddedId . The questionCompletionId and questionCompletionId attributes are a foreign key for some other objects, so I put below the whole objects of these objects with the @MapsId annotation as @MapsId .
@javax.persistence.Entity @org.hibernate.annotations.Entity(dynamicUpdate = true) @Table(name = "extended_question_answer") public class QuestionCompletionAnswer implements Serializable { @EmbeddedId private QuestionCompletionAnswerPK id; @ManyToOne @MapsId(value = "questionCompletionId") @JoinColumn(name = "question_completion_id", nullable = false, insertable = false, updatable = false) protected QuestionCompletion questionCompletion; @ManyToOne @MapsId(value = "extendedQuestionId") @JoinColumn(name = "extended_question_id", nullable = false, insertable = false, updatable = false) protected ExtendedQuestion extendedQuestion; }
Could you tell if my annotations are correct? Perhaps I mixed up several approaches. Or I can’t save my main object with all its children in this case.
EDIT
Now my comparison looks like this:
@javax.persistence.Entity @org.hibernate.annotations.Entity(dynamicUpdate = true) @Table(name = "question_completion") public class QuestionCompletion implements Serializable { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "question_completion_gen") @SequenceGenerator(name = "question_completion_gen", sequenceName = "question_completion_id_seq") @Column(name = "question_completion_id") private Long id; @OneToMany(cascade = CascadeType.ALL, mappedBy = "questionCompletion") protected List<QuestionCompletionAnswer> answers; }
The code for the QuestionCompletionAnswerPK class is the same.
@javax.persistence.Entity @org.hibernate.annotations.Entity(dynamicUpdate = true) @Table(name = "extended_question_answer") public class QuestionCompletionAnswer implements Serializable { @EmbeddedId private QuestionCompletionAnswerPK id; @ManyToOne(cascade = CascadeType.PERSIST) @MapsId(value = "questionCompletionId") @JoinColumn(name = "question_completion_id", nullable = false) protected QuestionCompletion questionCompletion; @ManyToOne @MapsId(value = "extendedQuestionId") @JoinColumn(name = "extended_question_id", nullable = false) protected ExtendedQuestion extendedQuestion; }
With this mapping, I still get the same exception.
EDIT # 2 However, when I changed the QuestionCompletionAnswer class as follows:
@javax.persistence.Entity @org.hibernate.annotations.Entity(dynamicUpdate = true) @Table(name = "extended_question_answer") public class QuestionCompletionAnswer implements Serializable { @EmbeddedId private QuestionCompletionAnswerPK id; @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "question_completion_id", nullable = false, insertable = false, updatable = false) protected QuestionCompletion questionCompletion; @ManyToOne @JoinColumn(name = "extended_question_id", nullable = false, insertable = false, updatable = false) protected ExtendedQuestion extendedQuestion; }
I get this exception:
Caused by: org.hibernate.id.IdentifierGenerationException: null id generated for:class com.example.model.domain.QuestionCompletionAnswer