我们正在从Hibernate本机标准转向JPA标准查询,将hibernate从4.3.11升级到5.2.12,并发现了不同的行为 . 以前的休眠标准使用带有连接的单个查询来急切获取一对多关联实体,但JPA使用单独的查询来获取每个根实体的关联实体 .
我知道我可以像 entityRoot.fetch("attributes", JoinType.INNER);
那样明确设置获取模式,但是我们需要在一些AbstractDao实现中执行它,该实现应该适用于任何急切的一对多关联,因此无法明确设置它 .
因此,我可以以某种方式告诉JPA标准,在默认情况下使用连接而不是针对每个根实体的单独查询,在单个查询中急切获取关联实体吗?
代码示例:
CriteriaBuilder builder = createCriteriaBuilder();
CriteriaQuery<T> criteriaQuery = builder.createQuery(getEntityClass());
Root<T> entityRoot = criteriaQuery.from(getEntityClass());
criteriaQuery.select(entityRoot);
criteriaQuery.where(builder.equal(entityRoot.get("param1"), "value"));
return getEntityManager().createQuery(criteriaQuery).getResultList();
1 回答
简答
您无法以这种方式配置它,但您可以实现必要的行为 .
答案很长
正如您在Hibernate 5.2 User Guide中所读到的,有几种方法可以应用提取策略:
@Fetch annotation
JPQL / HQL查询 - fetch join
JPA标准查询 - FetchParent::fetch
JPA实体图 - attributeNodes
Hibernate Profiles - fetchOverrides
@Fetch
annotation是一种应用提取策略的静态方法,FetchMode.JOIN
完全按照您的描述工作:问题是,即使您使用
@Fetch(FetchMode.JOIN)
注释标记attributes
集合,它也将是overridden:没有
FetchParent::fetch
的JPA Criteria查询也会这样做 .由于您需要一个抽象DAO的通用解决方案,可能的方法是使用反射处理所有渴望的一对多关联:
当然,为每个查询调用反射都是低效的 . 您可以从Metamodel获取所有已加载的
@Entity
类,对其进行处理,并存储结果以供进一步使用: