java - FetchMode.JOIN 急切地获取成员列表显然会产生笛卡尔积

标签 java hibernate join

我正在尝试优化涉及多个中的所有书籍视频的复杂操作(这不是实际的域,出于保密原因)。

代码最初使用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 所建议的。 更多信息请参阅

Hibernate does not return distinct results for a query with outer join fetching enabled for a collection (even if I use the distinct keyword)?

上面提供的链接中可能的解决方案

  1. 使用 Set

    List<Library> library = ...; return new ArrayList<Library>(new LinkedHashSet<Library>(library));

  2. 使用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/

相关文章:

java - 当 jackson 自动检测 setter 时,我可以强制它使用帕斯卡大小写吗?

java - Drools KieScanner——是否可以从可执行文件中加载settings.xml?

Spring找不到类[org.hibernate.ejb.HibernatePersistence]

java - Hibernate 中泛型类的映射

sql - 在单个sql查询中选择多个表

MySQL 检查结果是否被收藏

Java 8 : how to 'JOIN' two Maps having the same Keys?

java - 安装后如何将应用程序注册为启动器

java - 在我的 Tapestry 网站上编写搜索代码?

java - Hibernate 中层次结构的高效表示