简体   繁体   English

Hibernate DTO Projections N+1 查询

[英]Hibernate DTO Projections N+1 queries

Just experimented an interesting fact while using Hibernate & Spring Data JPA.刚刚在使用 Hibernate 和 Spring 数据 JPA 时实验了一个有趣的事实。 I have the following setup DTO and Entity:我有以下设置 DTO 和实体:

@Getter
@Setter
public class ClassDto {
     private String id;
     private String name;

      public ClassDto(Entity e) {
         this.id = e.id;
        this.name = e.name;
      }

      public ClassDto(String id, String name) {
          this.id = id;
          this.name = name;
      }
}

@Entity
@Setter
@Getter
public class Entity {
     @Id String id;
     String name;
}

Why this query got executed N+1 times.为什么这个查询被执行了 N+1 次。

select new org.xyz.ClassDto(e) from Entity e

While this one with entity destructured just once虽然这个实体只解构了一次

select new org.xyz.ClassDto(e.id, e.name) from Entity e

I want only a logical explanation about how things works underground.我只想要一个关于地下事物如何运作的合乎逻辑的解释。

Thanks谢谢

I guess that you are using a query like this:我猜你正在使用这样的查询:

select new org.xyz.ClassDto(e.toManyAssociation) from Entity e

In this case, Hibernate will pass in a proxy instead of a fully initialized entity, so when you access the data of that object in the constructor, Hibernate will lazy load the object. In this case, Hibernate will pass in a proxy instead of a fully initialized entity, so when you access the data of that object in the constructor, Hibernate will lazy load the object. You can solve that by joining the association and passing the join alias instead.您可以通过加入关联并改为传递加入别名来解决此问题。

I think you might be interested inBlaze-Persistence Entity Views though.我想你可能对Blaze-Persistence Entity Views感兴趣。

I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids.我创建了该库,以允许在 JPA 模型和自定义接口或抽象 class 定义的模型之间轻松映射,例如 Spring Data Projections on steroids。 The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model.这个想法是您以您喜欢的方式定义您的目标结构(域模型),并通过 JPQL 表达式将 map 属性(吸气剂)定义为实体 model。

A DTO model for your use case could look like the following with Blaze-Persistence Entity-Views:使用 Blaze-Persistence Entity-Views 的 DTO model 可能如下所示:

@EntityView(Entity.class)
public interface ClassDto {
    @IdMapping
    Long getId();
    String getName();
}

Querying is a matter of applying the entity view to a query, the simplest being just a query by id.查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

ClassDto a = entityViewManager.find(entityManager, ClassDto.class, id);

The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features Spring 数据集成允许您几乎像 Spring 数据投影一样使用它: https://persistence.blazebit.com/documentation/entity-view/manual-html/。

Page<ClassDto> findAll(Pageable pageable);

The best part is, it will only fetch the state that is actually necessary!最好的部分是,它只会获取实际需要的 state!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM