Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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
Hibernate JPQL急切地获取元素_Hibernate_Spring Data Jpa_Jpql - Fatal编程技术网

Hibernate JPQL急切地获取元素

Hibernate JPQL急切地获取元素,hibernate,spring-data-jpa,jpql,Hibernate,Spring Data Jpa,Jpql,假设如下: @Query("SELECT new so.dto.CustomerWithTotal(s, sum(sb.amount)) from Customer s LEFT join fetch Bills sb ON sb.customer.sq=s.sq and sb.periodFrom <= ?3 and sb.periodTo >= ?2 WHERE s.department.sq=?1 group by s") List<Cus

假设如下:

   @Query("SELECT new so.dto.CustomerWithTotal(s, sum(sb.amount)) from Customer s LEFT join fetch Bills sb ON sb.customer.sq=s.sq and sb.periodFrom <= ?3 and sb.periodTo >= ?2 WHERE s.department.sq=?1 group by s")
   List<CustomerWithTotal> findCustWithOrderTotal(Long departmentId, LocalDate from, LocalDate to);
我正试图把顾客连同他在特定时期内的订单总数一起拿来。但是,当我检查实际执行的查询时,我看到如下情况:

Hibernate: select customer.id as col_0_0_, sum(bill.amount) as col_1_0_ from customers...
Hibernate: select customer.id as cpx1_19_0_, customer.jpa_version as jpa_vers2_19_0_, ...
Hibernate: select customer.id as cpx1_19_0_, customer.jpa_version as jpa_vers2_19_0_, ...

Hibernate只在第一个查询中获取id,然后分别请求每个客户,从而产生N+1个查询。如何让Hibernate在第一次查询中急切地获取
customer
?最好不要在
CustomerWithBillTotal

中列出所有
customer
字段。如果要将实体别名传递给JPQL中的构造函数,Hibernate必须具体化完整的对象,因此它会在某个时间以某种方式获取所有字段。据我所知,如果传递实体别名,Hibernate中构造函数表达式的当前实现将始终传递代理,因此您看到的二次加载是由于Hibernate加载状态。如果只想获取实际需要的字段,则需要精确地列出它们

你可能也喜欢你所能提供的

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

在Blaze持久性实体视图中,您的用例的DTO模型可能如下所示:

@EntityView(Customer.class)
public interface CustomerWithBillTotal {
    @IdMapping("sq")
    Integer getId();
    String getCustomerName();
    // Other customer mappings you need...

    // Assuming you have a one-to-many association named "bills" in Customer
    @Mapping("COALESCE(SUM(bills.amount), 0)")
    // You can also use this if you don't have that association
    // @Mapping("COALESCE(SUM(Bills[customer.sq = VIEW(sq) AND periodFrom <= :periodFrom and periodTo >= :periodTo].amount), 0)")
    BigDecimal getAmount();
}
@EntityView(Customer.class)
public interface CustomerWithBillTotal {
    @IdMapping("sq")
    Integer getId();
    String getCustomerName();
    // Other customer mappings you need...

    // Assuming you have a one-to-many association named "bills" in Customer
    @Mapping("COALESCE(SUM(bills.amount), 0)")
    // You can also use this if you don't have that association
    // @Mapping("COALESCE(SUM(Bills[customer.sq = VIEW(sq) AND periodFrom <= :periodFrom and periodTo >= :periodTo].amount), 0)")
    BigDecimal getAmount();
}
   List<CustomerWithTotal> findByDepartmentId(Long departmentId, @OptionalParam("periodFrom") LocalDate from, @OptionalParam("periodTo") LocalDate to);