我开始在JPA 2.1中使用新的实体图形功能来指定必须加载的Lazy集合。 考虑以下课程:
@Entity
@NamedQueries({
@NamedQuery(name="findWithFilterAttr","select a from A a where a.filterAttribute like :filter")
})
@NamedEntityGraphs({
@NamedEntityGraph(name = "graph.childs", attributeNodes = @NamedAttributeNode("childs"))})
public class A{
@Id
private long id;
@OneToMany(mappedBy="parent")
private List<B> childs;
private String filterAttribute;
}
@Entity
public class B{
@Id
private long id;
@ManyToOne
private A parent;
}
当我执行命名查询以获取具有实体图提示的A实体列表时,我得到一个带有重复A实体的集合。 如何只加载A实体一次。
我正在使用:
答案 0 :(得分:5)
我终于解决了这个问题,我在命名查询中添加了DISTINCT,现在一切正常.... 导致该错误是因为当JPA Provider找到实体图提示时,它会创建一个带子表的LEFT JOIN。 没有实体图的原始查询:
11:55:28,950 INFO [stdout] (default task-23) Hibernate:
11:55:28,950 INFO [stdout] (default task-23) select
11:55:28,951 INFO [stdout] (default task-23) entitya0_.id as id1_0_0_,
11:55:28,951 INFO [stdout] (default task-23) childs1_.id as id1_1_1_,
11:55:28,951 INFO [stdout] (default task-23) entitya0_.filter as filter2_0_0_,
11:55:28,951 INFO [stdout] (default task-23) childs1_.parent_id as parent_i2_1_1_,
11:55:28,951 INFO [stdout] (default task-23) childs1_.parent_id as parent_i2_0_0__,
11:55:28,951 INFO [stdout] (default task-23) childs1_.id as id1_1_0__
11:55:28,951 INFO [stdout] (default task-23) from
11:55:28,951 INFO [stdout] (default task-23) EntityA entitya0_
11:55:28,951 INFO [stdout] (default task-23) left outer join
11:55:28,952 INFO [stdout] (default task-23) EntityB childs1_
11:55:28,952 INFO [stdout] (default task-23) on entitya0_.id=childs1_.parent_id
11:55:28,952 INFO [stdout] (default task-23) where
11:55:28,952 INFO [stdout] (default task-23) entitya0_.filter like ?
使用distinct和entity graph进行查询:
11:57:25,051 INFO [stdout] (default task-24) Hibernate:
11:57:25,052 INFO [stdout] (default task-24) select
11:57:25,052 INFO [stdout] (default task-24) distinct entitya0_.id as id1_0_0_,
11:57:25,052 INFO [stdout] (default task-24) childs1_.id as id1_1_1_,
11:57:25,052 INFO [stdout] (default task-24) entitya0_.filter as filter2_0_0_,
11:57:25,052 INFO [stdout] (default task-24) childs1_.parent_id as parent_i2_1_1_,
11:57:25,052 INFO [stdout] (default task-24) childs1_.parent_id as parent_i2_0_0__,
11:57:25,052 INFO [stdout] (default task-24) childs1_.id as id1_1_0__
11:57:25,052 INFO [stdout] (default task-24) from
11:57:25,052 INFO [stdout] (default task-24) EntityA entitya0_
11:57:25,052 INFO [stdout] (default task-24) left outer join
11:57:25,052 INFO [stdout] (default task-24) EntityB childs1_
11:57:25,052 INFO [stdout] (default task-24) on entitya0_.id=childs1_.parent_id
11:57:25,052 INFO [stdout] (default task-24) where
11:57:25,052 INFO [stdout] (default task-24) entitya0_.filter like ?
答案 1 :(得分:1)
一个小补充。
我和你有同样的问题。
我认为这种行为是出乎意料的,可能是休眠的一个缺陷。
不应该指定distinct
,因为它是JPQL查询中直接指定的提取的情况。
由于实施的限制,您的解决方案是一种解决方法。
通过检查代码(方法needsDistincting
中的list()
标志的计算,grepcode处可用),有2个解决方案: