java关联实体查询_JPA Criteria使用带有连接而不是多个查询的SINGLE查询来查询急切获取关联实体...

简答

您无法以这种方式配置它,但您可以实现必要的行为 .

答案很长

正如您在Hibernate 5.2 User Guide中所读到的,有几种方法可以应用提取策略:

@Fetch annotation是一种应用提取策略的静态方法, FetchMode.JOIN 完全按照您的描述工作:

本质上是EAGER的抓取方式 . 要获取的数据是通过使用SQL外连接获得的 .

问题是,即使您使用 @Fetch(FetchMode.JOIN) 注释标记 attributes 集合,它也将是overridden:

我们之所以不使用JPQL查询来获取多个Department实体,是因为查询获取指令会覆盖FetchMode.JOIN策略 . 要使用JPQL查询获取多个关系,必须使用JOIN FETCH指令 . 因此,FetchMode.JOIN对于通过其标识符或natural-id直接获取实体时非常有用 .

没有 FetchParent::fetch 的JPA Criteria查询也会这样做 .

由于您需要一个抽象DAO的通用解决方案,可能的方法是使用反射处理所有渴望的一对多关联:

Arrays.stream(getEntityClass().getDeclaredFields())

.filter(field ->

field.isAnnotationPresent(OneToMany.class))

.filter(field ->

FetchType.EAGER == field.getAnnotation(OneToMany.class).fetch())

.forEach(field ->

entityRoot.fetch(field.getName(), JoinType.INNER));

当然,为每个查询调用反射都是低效的 . 您可以从Metamodel获取所有已加载的 @Entity 类,对其进行处理,并存储结果以供进一步使用:

Metamodel metamodel = getEntityManager().getMetamodel();

List entityClasses = metamodel.getEntities().stream()

.map(Type::getJavaType)

.collect(Collectors.toList());

Map> fetchingAssociations = entityClasses.stream()

.collect(Collectors.toMap(

Function.identity(),

aClass -> Arrays.stream(aClass.getDeclaredFields())

.filter(field ->

field.isAnnotationPresent(OneToMany.class))

.filter(field ->

FetchType.EAGER == field.getAnnotation(OneToMany.class).fetch())

.map(Field::getName)

.collect(Collectors.toList())

));


版权声明:本文为weixin_30229705原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。