java - 使用 JPA/Hibernate 构造函数表达式防止 "n+1 selects"?

标签 java hibernate jpa select-n-plus-1

我有两个实体,ItemData,以及一个 DTO 类 ItemDataItemDataItemData 组成,没有 JPA 映射。为了检索填充的 ItemData 列表,我在 JPQL 中使用构造函数表达式:

select new my.package.ItemData(i, d)
from Item i, Data d
where i.id = d.itemId

这就是 Hibernate 正在做的事情:它不是同时获取 ItemData 的数据,而是先获取它们的 ID,然后获取 n< 中的数据/em> 单独的选择语句。有没有办法改变这种行为?

Hibernate:
    select
        item0_.id as col_0_0_,
        data1_.id as col_1_0_ 
    from
        ITEM item0_,
        DATA data1_

Hibernate: 
    select
        item0_.no as no1_0_,
        item0_.description as description1_0_,
        item0_.organic as bio1_0_,
        item0_.gluten as gluten1_0_,
        item0_.laktose as laktose1_0_
    from
        ITEM item0_ 
    where
        item0_.id=?

Hibernate: 
    select
        data0_.amount as amount1_3_0_,
        data0_.avg as avg3_0_,
        data0_.total as total3_0_
    from
        DATA data0_ 
    where
        data0_.id=?

Hibernate: 
    select
        item0_.no as no1_0_,
        item0_.description as description1_0_,
        item0_.organic as bio1_0_,
        item0_.gluten as gluten1_0_,
        item0_.laktose as laktose1_0_
    from
        ITEM item0_ 
    where
        item0_.id=?

Hibernate: 
    select
        data0_.amount as amount1_3_0_,
        data0_.avg as avg3_0_,
        data0_.total as total3_0_
    from
        DATA data0_ 
    where
        data0_.id=?

...and so on...        

最佳答案

使用左连接获取怎么样?
我承认我没有使用 CTOR 表达式,但是当我需要获取父实体及其子实体时,我使用了左连接获取,它总是很有魅力。
我只能假设,既然我们在这里处理对象的构造,
Hibernate 不“想要”留下“部分构造”的对象(或者说 - 处于“惰性求值状态”的对象),并且由于您没有使用“左连接获取”执行“急切获取”,因此它执行 N +1 获取:
首先,它获取所有 ID,然后针对每个相关 ID 执行另一次获取。
阅读有关左连接获取的更多信息 here (只需在页面中查找“left join fetch”即可)

关于java - 使用 JPA/Hibernate 构造函数表达式防止 "n+1 selects"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12782029/

相关文章:

java - JPA 错误后从 PostgreSQL 连接关闭中恢复

java - spring jpa @transaction 不回滚

java - 从 FileInputStream 或 FileReader 中剥离 HTTP header 信息

java - 接口(interface)之间的转换

java - org.apache.tomcat.util.bcel.classfile.ClassFormatException : Invalid byte tag in constant pool: 15

java - Spring MVC 和 Hibernate : How to print out left joined fields?

java - 需要帮助了解 mySQL、POJO、hibernate 和 JSP

java - PrimeFaces SelectOneMenu : Empty String is submitted as null

java - Hibernate 对具有复合键的子实体执行错误的插入顺序

mysql - 如何在映射到 mysql 中的 varbinary 值的 byte[] hibernate 实体上创建 Id