Hibernate inheritance strategy = InheritanceType.JOINED & onetoMany with spring-data-jpa
For some reason, I cannot get the combination of the Hibernate Inheritance = InheritanceType.JOINED and onetoMany strategy. The entities are listed below.
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="OBJECT_TYPE")
public abstract class ExamObject {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "examid", nullable = false)
private Exam exam;
}
@Entity
@DiscriminatorValue("Q")
public class ExamQuestion extends ExamObject{
private Integer questionNumber;
private String questionDesc;
}
@Entity
public class Exam {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer examid;
private String examName;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "exam")
private Set<ExamObject> object
}
My Spring Boot Starter Class
@SpringBootApplication
public class ExamApp implements CommandLineRunner {
@Autowired
private ExamQuestionRepository examQuestionRepository;
@Autowired
private ExamRepository examRepository;
public static void main(String[] args) {
SpringApplication.run(ExamApp.class, args);
}
@Override
@Transactional
public void run(String... arg0) throws Exception {
Exam exam = new Exam();
exam.setExamName("Exam1");
examRepository.save(exam);
String[] questions = new String[]{"Question1,Question2"};
ArrayList<ExamQuestion> examQuestions = new ArrayList<ExamQuestion();
int index = 0;
for(String questionNoDesc: questions){
index++;
ExamQuestion examQuestion = new ExamQuestion();
examQuestion.setQuestionDesc(questionNoDesc);
examQuestion.setQuestionNumber(index);
examQuestion.setExam(exam);
examQuestions.add(examQuestion);
}
examQuestionRepository.save(examQuestions);
Iterable<Exam> examGet = examRepository.findAll();
for (Exam exam2: examGet) {
System.out.println("Exam question is .. " +exam2.getObjects());
}
}
}
The problem is that whenever I type "Exam question is .. "+exam2.getObjects()
, I always get null. How can I get this to work?
source to share
As explained in the comment in the original question, the problem is that the object graph is not properly maintained. One extra line of code for the following function fixed the problem. exam.setObjects(examQuestions);
added
@Override
@Transactional
public void run(String... arg0) throws Exception {
Exam exam = new Exam();
exam.setExamName("Exam1");
examRepository.save(exam);
String[] questions = new String[]{"Question1,Question2"};
ArrayList<ExamQuestion> examQuestions = new ArrayList<ExamQuestion();
int index = 0;
for(String questionNoDesc: questions){
index++;
ExamQuestion examQuestion = new ExamQuestion();
examQuestion.setQuestionDesc(questionNoDesc);
examQuestion.setQuestionNumber(index);
examQuestion.setExam(exam);
examQuestions.add(examQuestion);
}
examQuestionRepository.save(examQuestions);
exam.setObjects(examQuestions);
Iterable<Exam> examGet = examRepository.findAll();
for (Exam exam2: examGet) {
System.out.println("Exam question is .. " +exam2.getObjects());
}
}
source to share
Probably the problem:
@OneToMany (fetch = FetchType.LAZY, mappedBy = "exam") private Set object
When you download any thing when you download LAZY FetchType.LAZY
. This will get the whole object from ie Exam parent table here, but will not query child / dependent tables for data.
eg Here it won't hit the ExamObject to get its data, it just replaces that with a proxy object. Thus, if you ask for this object, you will get zero as a result.
Try to execute the request with FetchType.EAGER
source to share