Search code examples
javahibernatejpaplayframeworkplayframework-1.x

Hibernate and Playframework 1.2.4 : strange behaviour when querying member collection size


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 ?


Solution

  • 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);