Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 防止;n+;1选择“;使用JPA/Hibernate构造函数表达式?_Java_Hibernate_Jpa_Select N Plus 1 - Fatal编程技术网

Java 防止;n+;1选择“;使用JPA/Hibernate构造函数表达式?

Java 防止;n+;1选择“;使用JPA/Hibernate构造函数表达式?,java,hibernate,jpa,select-n-plus-1,Java,Hibernate,Jpa,Select N Plus 1,我有两个实体,Item和Data,还有一个DTO类ItemData项目数据由项目和数据组成,没有JPA映射。为了检索填充的ItemData列表,我在JPQL中使用了一个构造函数表达式: select new my.package.ItemData(i, d) from Item i, Data d where i.id = d.itemId Hibernate就是这样做的:它不是同时获取项和数据的数据,而是先获取它们的ID,然后在n个单独的select语句中获取数据。有没有办法改变这种行为 H

我有两个实体,
Item
Data
,还有一个DTO类
ItemData
<代码>项目数据由
项目
数据
组成,没有JPA映射。为了检索填充的ItemData列表,我在JPQL中使用了一个构造函数表达式:

select new my.package.ItemData(i, d)
from Item i, Data d
where i.id = d.itemId
Hibernate就是这样做的:它不是同时获取
数据
的数据,而是先获取它们的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...        

使用left-join-fetch怎么样
我承认我没有使用CTOR表达式,但当我需要获取父实体及其子实体时,我使用左连接获取,它总是像一个符咒一样工作
我只能假设,因为我们这里讨论的是对象的构造,
Hibernate不“希望”让对象“部分构造”(或者说,对象处于“惰性评估状态”),并且由于您没有使用“左连接获取”执行“急切获取”,因此它执行N+1获取:
它首先获取所有ID,然后对每个相关ID执行另一次获取

阅读有关左连接获取的更多信息(只需在页面上查找“左连接获取”)

这是一个完美的左连接获取用例

我创建了这个库,以便在JPA模型和自定义接口或抽象类定义的模型之间进行简单的映射,类似于类固醇上的Spring数据投影。其思想是以您喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(getter)映射到实体模型

我想你的实体模型是这样的

@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;
  ...
}
在Blaze持久性实体视图中,您的用例的DTO模型可能如下所示:

@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数据集成允许您像使用Spring数据投影一样使用它:

@DataNucleus为什么要删除JPA标记?仅仅是因为您将问题中的所有内容表示为特定于Hibernate的(Hibernate SQL等)。有JPA背景的人没有什么可以帮你的。。。我不同意这一点。有一些JPQL表达式会影响提供者的行为(例如“join-fetch”)。您需要将项和数据映射为一个OneToMany语句,以便Hibernate知道有一个集合结构在起作用。然后将自动生成联接。为什么会有否决票?我愿意改进…谢谢你-有什么东西我可以用在构造函数表达式上,就像连接的fetch关键字一样吗?@Mulmoth-我不知道