Dhe*_*rik 25 java hibernate jpa hql jpql
我在大型应用程序中遇到EAGER关系问题.此应用程序中的某些实体EAGER与其他实体有关联.这在某些功能中变成了"毒药".
现在我的团队需要优化这些功能,但我们不能将获取类型更改为LAZY,因为我们需要重构整个应用程序.
所以,我的问题:是否有办法在我返回的实体中忽略EAGERs关联来执行特定查询?
示例:当我有这个实体Person时,我想在查询人员时不带地址列表.
@Entity
public class Person {
@Column
private String name;
@OneToMany(fetch=FetchType.EAGER)
private List<String> address;
}
Query query = EntityManager.createQuery("FROM Person person");
//list of person without the address list! But how???
List<Person> resultList = query.getResultList();
Run Code Online (Sandbox Code Playgroud)
谢谢!
更新
我找到的唯一方法是不返回实体,只返回实体的某些字段.但我想找到一个可以返回实体的解决方案(在我的例子中,Person实体).
我在想是否可以在Hibernate中将同一个表映射两次.通过这种方式,我可以在没有EAGER关联的情况下映射同一个表.在一些情况下,这对我有帮助......
Mil*_*lan 11
如果您使用的是JPA 2.1(Hibernate 4.3+),您可以使用@NamedEntityGraph实现您想要的效果.
基本上,您可以像这样注释您的实体:
@Entity
@NamedEntityGraph(name = "Persons.noAddress")
public class Person {
@Column
private String name;
@OneToMany(fetch=FetchType.EAGER)
private List<String> address;
}
Run Code Online (Sandbox Code Playgroud)
然后使用提示来获取没有地址的Person,如下所示:
EntityGraph graph = this.em.getEntityGraph("Persons.noAddress");
Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph);
return this.em.findAll(Person.class, hints);
Run Code Online (Sandbox Code Playgroud)
有关此主题的更多信息,请点击此处.
当您使用获取图时,只会急切地获取放在@NamedEntityGraph中的字段.
在没有提示的情况下执行的所有现有查询将保持不变.
更新(09/06/2020):
该问题已在 5.4.11 版本中解决。我现在无法测试,但预计图中未包含的 JPA 实体图属性应保持卸载状态,即使它们已声明EAGER。
原答案
经过这么多年,在 Hibernate 上覆盖 EAGER 映射是不可能的。来自最新的 Hibernate 文档(5.3.10.Final):
尽管 JPA 标准规定您可以在运行时使用 javax.persistence.fetchgraph 提示覆盖 EAGER 获取关联,但目前,Hibernate 未实现此功能,因此无法延迟获取 EAGER 关联。有关更多信息,请查看 HHH-8776 Jira 问题。
在执行 JPQL 查询时,如果省略了 EAGER 关联,Hibernate 将针对需要急切获取的每个关联发出辅助选择,这可能导致 dto N+1 查询问题。
出于这个原因,最好使用 LAZY 关联,并且只在每个查询的基础上急切地获取它们。
和:
EAGER 获取策略不能在每个查询的基础上被覆盖,因此即使您不需要关联也总是会被检索。此外,如果您忘记在 JPQL 查询中 JOIN FETCH EAGER 关联,Hibernate 将使用辅助语句对其进行初始化,这反过来会导致 N+1 查询问题。
| 归档时间: |
|
| 查看次数: |
11638 次 |
| 最近记录: |