I have three classes.
Class EntranceExam :
@Entity
public class EntranceExam extends GenericModel implements Comparable<EntranceExam> {
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "entranceExam")
public List<Examination> examinations;
}
Class Examination :
@Entity
public class Examination extends Model implements Comparable<Examination> {
@ManyToOne(optional = false)
public EntranceExam entranceExam;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "examination")
public Question mainQuestion;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "examination", fetch = FetchType.LAZY)
public Set<Question> questions = new HashSet<Question>();
}
Class Question :
@Entity
public class Question extends GenericModel implements Serializable,
Comparable<Question> {
@ManyToOne
public Examination examination;
@Sort(type = SortType.NATURAL)
@OneToMany(fetch = FetchType.EAGER, mappedBy = "parentQuestion", cascade = { CascadeType.ALL })
public Set<Question> childQuestions;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "PARENT_ID", nullable = true)
public Question parentQuestion;
}
So, when I use it all together :
EntranceExam entranceExam = EntranceExam.findById(id);
System.out.println(entranceExam.examinations.size());
It returns the number of questions in entranceExam's examinations instead of the numbers of examinations. If I simplify, the matching query in MySQL log looks like this :
select examinations0_.entranceExam_id as entranceExam4_108_3_,
examinations0_.id as id3_
from Examination examinations0_
left outer join Question question1_
on examinations0_.id=question1_.examination_id
left outer join Question question2_
on question1_.PARENT_ID=question2_.questionId
where epreuves0_.entranceExam_id=4;
Where is the problem in my Java code ?
You may need to wrap entranceExam.examinations
into a HashSet
, by default hibernate creates one parent object for each child.
Set examinations = new HashSet(entranceExam.examinations)
An other way is to set the distinct strategy
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);