Thanks in advance for your help. I have, what I consider to be a complicated relationship between entities and I am not sure the best way to implement. I've tried numerous ways with no luck.
As you can see below, I have a Test entity which represents a test that can be taken by a student, it contains a list of Question entities (OTMany.)
A TestRef represents an attempt made by a student to take the test, it contains a list of AnsweredQuestion entities (OTMany.) AnsweredQuestion extends Question.
My test data has one Test record, with 30 related Questions records. One TestRef record, with 3 related AnsweredQuestion records. This basically means that the student has only answered 3 of the possible 30 questions.
By default, if I fetch the TestRef, it contains 3 AnsweredQuestions. What I'd like to do is figure out a way to have Hibernate automatically populate my list of AnsweredQuestions in my TestRef based on the Questions table (WHERE Question.tableId = TestRef.Table.Id), not the AnsweredQuestions table. In SQL, this would just be a basic LEFT JOIN. I've tried doing this with a custom @Loader using a @NamedNativeQuery (see below), but there is a documented bug that is preventing this from working. (
http://opensource.atlassian.com/project ... e/HHH-3273)
My hunch is that there is a much cleaner way to do this, but I am just not sure of what that solution is. If you have any wisdom in this area, I could sure use it right now...
Thanks,
Matt
@NamedNativeQuery(
name="testAnswers",
query="select q.id AS id,q.correctAnswer AS correctAnswer,q.feedback AS feedback,q.optionA AS optionA, " +
"q.optionB AS optionB,q.optionC AS optionC,q.optionD AS optionD,q.questionNumber AS questionNumber," +
"q.text AS text,q.testId AS testId,ifnull(aq.value, 'D') AS value,tr.id AS testRefId,q.id AS questionId " +
"from ((question q left join answeredquestion aq on((aq.questionId = q.id))) " +
"join test t on((q.testId = t.id)))" +
"join testRef tr on((tr.id = ?))", resultClass = AnsweredQuestion.class)
@Entity
public class Test
{
@Id
@GeneratedValue
private int id;
@OneToMany(fetch = FetchType.LAZY, mappedBy="test")
@OrderBy("questionNumber")
private List<Question> questions;
}
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Question
{
@Id
@GeneratedValue
private int id;
@ManyToOne(optional=false)
@JoinColumn(name="testId")
private Test test;
@Column(length=1000, nullable=false)
@TextFieldAnnotation(maxLength=50, required=true)
private String text;
@Enumerated(EnumType.STRING)
@Column(length=1)
private AnswerEnum correctAnswer;
@Column(length=1000, nullable=false)
private String optionA;
@Column(length=1000, nullable=false)
private String optionB;
@Column(length=1000, nullable=false)
private String optionC;
@Column(length=1000, nullable=false)
private String optionD;
@Column(columnDefinition="INTEGER DEFAULT 0")
private int questionNumber;
}
public class TestRef
{
@Id
@GeneratedValue
private int id;
@OneToOne(optional=false)
@JoinColumn(name="testId")
private Test test;
@OneToMany(fetch = FetchType.EAGER)
@OrderBy("questionNumber")
private List<AnsweredQuestion> answers;
}
@Entity
@PrimaryKeyJoinColumn(name="questionId")
public class AnsweredQuestion extends Question
{
@ManyToOne(optional = false, fetch=FetchType.EAGER)
@JoinColumn(name = "testRefId")
private TestRef testRef;
@Enumerated(EnumType.STRING)
@Column(length = 1, nullable = true)
private AnswerEnum value;
}