Please see the attached [^HHH-13067.zip] file for a self-contained example, runnable using {{mvn clean test}} on JDK 8 .
There are two entity classes, the {{Parent}} references the {{Child}} using {{@ManyToMany(fetch=FetchType.EAGER)}}. Suppose that a {{Parent}} instance references more than one {{Child}} instance.
The {{session.createCriteria(Parent.class).list()}} legacy Criteria API query is translated into an SQL query using {{LEFT OUTER JOIN}}, so the {{Parent}} *rows are returned multiple times*.
The following alternatives all produce the correct result - by executing two separate {{SELECT}} statements: -- Using the new JPA CriteriaQuery API to build the query -- Using {{FetchType.LAZY}} instead of {{FetchType.EAGER}} in the entity definition -- Adding {{@Fetch(FetchMode.SUBSELECT)}} to the entity definition - by filtering the result set for distinct values: -- Adding {{criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)}} to the query
Suggestion: when the legacy Criteria API builds the SQL query, it should default to {{FetchMode.SUBSELECT}} if the {{@ManyToMany}} relation is defined with {{FetchType.EAGER}}. |
|