我正在尝试优化涉及多个库
中的所有书籍
和视频
的复杂操作(这不是实际的域,出于保密原因)。
代码最初使用Criteria
加载所有Libraries
,然后通过迭代延迟加载成员Books
。我基本上添加了几个 FetchMode
子句:
List<Library> library = session
.createCriteria(Library.class)
.setFetchMode("books", FetchMode.JOIN)
.setFetchMode("videoShelves.videos", FetchMode.JOIN)
.list();
第二个 FetchMode
子句似乎有效,或者至少不会导致明显的问题。
但是,第一个将 Library
的数量从 6 个增加到 248 个。因此在我看来,每个 Library
可能会为每个 复制一次>预订
它有。
将 FetchMode
添加到查询时,Hibernate 在什么条件下可能会创建意外的重复实例?
最佳答案
此行为的原因是 outer join
正如@TimBiegeleisen 所建议的。
更多信息请参阅
上面提供的链接中可能的解决方案
使用
Set
List<Library> library = ...; return new ArrayList<Library>(new LinkedHashSet<Library>(library));
使用
Criteria.DISTINCT_ROOT_ENTITY
结果转换器List<Library> library = session .createCriteria(Library.class) .setFetchMode("books", FetchMode.JOIN) .setFetchMode("videoShelves.videos", FetchMode.JOIN). .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) .list();
但是,最好的解决方案当然不是在一个请求中获取所有数据。例如,如果您想显示图书馆列表(例如,包含书籍数量),您可以使用投影来仅加载您想要的数据。
关于java - FetchMode.JOIN 急切地获取成员列表显然会产生笛卡尔积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35880849/