我有这样的东西
Entity1
@Id
String id1;
@OneToMany(Fetch = LAZY)
List<Entity2> list1;
...
Entity2
@Id
String id2;
@OneToMany(Fetch = LAZY)
List<Entity3> list2;
...
Entity3
@Id
String id3;
...
我想在同一个会话中初始化list1和list2。
entity1 = (Entity1) session
.createCriteria(Entity1.class)
.setFetchMode("list1", FetchMode.JOIN)
.uniqueResult();
我想不出一个合适的方法来初始化Entity2的第二个嵌套列表,而不使用Hibernate。initialize并引发N+1查询或使用EAGER。
1条答案
按热度按时间xv8emn3q1#
首先,不要使用遗留的Hibernate Criteria API,它已经被弃用,在Hibernate 6中被删除了。
您可以使用join提取来提取第一个集合,使用
@Fetch(FetchMode.SUBSELECT)
提取来提取第二个集合,但我认为这是Blaze-Persistence实体视图的完美用例。我创建这个库是为了允许在JPA模型和自定义接口或抽象类定义的模型之间进行简单的Map,就像Spring Data Projections一样。其思想是,您可以按照自己喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(getter)Map到实体模型。
使用Blaze-Persistence Entity-Views时,您的用例的DTO模型可能如下所示:
MULTISET
提取将聚合所有子行,从而避免N + 1问题。有关此问题的详细信息,请参阅文档。查询是将实体视图应用于查询的问题,最简单的是按id查询。
Entity1Dto a = entityViewManager.find(entityManager, Entity1Dto.class, id);
Spring Data 集成允许您像Spring Data 投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
最好的部分是,它只会获取实际需要的状态!