[英]Hibernate DTO Projections N+1 queries
剛剛在使用 Hibernate 和 Spring 數據 JPA 時實驗了一個有趣的事實。 我有以下設置 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;
}
為什么這個查詢被執行了 N+1 次。
select new org.xyz.ClassDto(e) from Entity e
雖然這個實體只解構了一次
select new org.xyz.ClassDto(e.id, e.name) from Entity e
我只想要一個關於地下事物如何運作的合乎邏輯的解釋。
謝謝
我猜你正在使用這樣的查詢:
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. 您可以通過加入關聯並改為傳遞加入別名來解決此問題。
我想你可能對Blaze-Persistence Entity Views感興趣。
我創建了該庫,以允許在 JPA 模型和自定義接口或抽象 class 定義的模型之間輕松映射,例如 Spring Data Projections on steroids。 這個想法是您以您喜歡的方式定義您的目標結構(域模型),並通過 JPQL 表達式將 map 屬性(吸氣劑)定義為實體 model。
使用 Blaze-Persistence Entity-Views 的 DTO model 可能如下所示:
@EntityView(Entity.class)
public interface ClassDto {
@IdMapping
Long getId();
String getName();
}
查詢是將實體視圖應用於查詢的問題,最簡單的就是通過 id 進行查詢。
ClassDto a = entityViewManager.find(entityManager, ClassDto.class, id);
Spring 數據集成允許您幾乎像 Spring 數據投影一樣使用它: https://persistence.blazebit.com/documentation/entity-view/manual-html/。
Page<ClassDto> findAll(Pageable pageable);
最好的部分是,它只會獲取實際需要的 state!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.