防止"n + 1选择"与JPA/休眠构造函数表达式? [英] Prevent "n+1 selects" with JPA/Hibernate constructor expression?

查看:79
本文介绍了防止"n + 1选择"与JPA/休眠构造函数表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two entities, Item and Data, and a DTO class ItemData. ItemData consists of Item and Data and has no JPA mapping. To retreive a list of populated ItemDatas, I use a constructor expression in JPQL:

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

这就是Hibernate正在做的事情:它不是先获取ItemData的数据,而是先获取其ID,然后再在 n 单独的select语句中获取数据.有办法改变这种行为吗?

This is what Hibernate is doing: Instead of fetching both the data of Item and Data, it gets their IDs first and the data afterwards in n separate select statements. Is there a way to change this behaviour?

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不会想要"将对象部分构造"(或者说,对象处于惰性评估状态"),并且由于您没有使用"left join fetch"执行"eager fetch",因此它执行N +1次获取:
首先,它获取所有ID,然后针对每个相关ID执行另一次获取.
此处了解更多有关左联接的信息在页面上查找左连接获取")

What about using left join fetch?
I admit I didn't use CTOR expressions, but when I need to fetch a parent entity and its children, I used left join fetch and it always worked like a charm.
I can only assume that since we're dealing here with construction of objects,
Hibernate does not "want" to leave an object "partially constructed" (or let's say - an object in "lazy evaluation state") , and since you did not perform an "eager fetch" using "left join fetch", it performs N+1 fetches:
At first it fetches all the IDs, and then for each relevant ID it performs another fetch.
Read more about left join fetch here (simply look for "left join fetch" at the page)

这篇关于防止"n + 1选择"与JPA/休眠构造函数表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆