Criteria API: Fetch of a list returns repeated main entity

后端 未结 2 686
醉话见心
醉话见心 2020-12-30 10:40

I have the following Entities; Ticket contains a set of 0,N WorkOrder:

@Entity
public class Ticket {

  ...

  @OneToMany(mappedBy=\"ticket\", cascade = Casc         


        
相关标签:
2条回答
  • 2020-12-30 11:07
    1. There is a difference between eager loading and fetch join. Eager loading doesn't mean that the data is loaded within the same query. It just means that it is loaded immediately, although by additional queries.

    2. The criteria is always translated to an SQL query. If you specify joins, it will be join in SQL. By the nature of SQL, this multiplies the data of the root entity as well, which leads to the effect you got. (Note that you get the same instance multiple times, so the root entity is not multiplied in memory.)

    There are several solutions to that:

    • use distinct(true)
    • Use the distinct root entity transformer (.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)).
    • When you don't need to filter by child properties, avoid the join
    • When you need to filter by child properties, filter by a subquery (DetachedCriteria).
    • Optimize the N+1 problem by using batch-size
    0 讨论(0)
  • 2020-12-30 11:28

    Have you tried calling distinct(true) on the CriteriaQuery?

    The JPA 2 specification, page 161, says:

    The DISTINCT keyword is used to specify that duplicate values must be eliminated from the query result.

    If DISTINCT is not specified, duplicate values are not eliminated.

    The javadoc also says:

    Specify whether duplicate query results will be eliminated.A true value will cause duplicates to be eliminated. A false value will cause duplicates to be retained. If distinct has not been specified, duplicate results must be retained.

    The reason why you don't need the distinct when the association is eagerly loaded is probably just that the association is not loaded using a fetch join, but using an additional query.

    0 讨论(0)
提交回复
热议问题