我有两个实体,Item
和Data
,以及一个DTO类ItemData
。 ItemData
由Item
和Data
组成,没有JPA映射。要检索已填充的ItemDatas列表,我在JPQL中使用构造函数表达式:
select new my.package.ItemData(i, d)
from Item i, Data d
where i.id = d.itemId
这就是Hibernate正在做的事情:它不是同时获取Item
和Data
的数据,而是首先获取其ID,然后在 n 中获取单独的select语句。有没有办法改变这种行为?
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...
答案 0 :(得分:2)
使用左连接提取怎么样?
我承认我没有使用CTOR表达式,但是当我需要获取父实体及其子实体时,我使用了左连接提取,它总是像魅力一样工作。
我只能假设,因为我们在这里处理物体的构造,
Hibernate不“希望”将对象“部分构造”(或者说 - “懒惰评估状态”中的对象),并且由于您没有使用“左连接提取”执行“急切提取”,它执行N +1次提取:
首先,它获取所有ID,然后对于每个相关ID,它执行另一次获取。
阅读有关左连接提取here的更多信息(只需在页面上查找“左连接提取”)
答案 1 :(得分:0)
这是Blaze-Persistence Entity Views的完美用例。
我创建了该库,以允许在JPA模型与自定义接口或抽象类定义的模型之间轻松进行映射,例如类固醇上的Spring Data Projections。这个想法是,您可以按自己喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(获取器)映射到实体模型。
我想您的实体模型看起来像这样吗?
@Entity
class Item {
@Id Long id;
String description;
@OneToMany(mappedBy = "item")
Data data;
...
}
@Entity
class Data {
@Id Long id;
@ManyToOne Item item;
Long amount;
BigDecimal avg;
...
}
针对您的用例的DTO模型可能与Blaze-Persistence Entity-Views相似,如下所示:
@EntityView(Item.class)
public interface ItemData {
@IdMapping
Long getNo();
String getDescription();
@Mapping("SUM(data.amount)")
Long getAmount();
}
查询是将实体视图应用于查询的问题,最简单的方法就是按ID查询。
ItemData a = entityViewManager.find(entityManager, ItemData.class, id);
Spring Data集成使您可以像使用Spring Data Projections一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features