我在使用 EntityGraph 覆盖某些属性上的延迟加载时遇到问题。
在以下示例中,
Person.picture
用 @ManyToOne(fetch = FetchType.LAZY)
注释。
如果我只加载单一类型的实体而没有任何连接,那么它工作得很好。
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<Person> root = criteriaQuery.from(Person.class);
criteriaQuery.select(root);
TypedQuery<Person> typedQuery = this.entityManager.createQuery(query);
EntityGraph<Person> entityGraph = entityManager.createEntityGraph(Person.class);
entityGraph.addAttributeNodes("picture");
query.setHint("javax.persistence.loadgraph", entityGraph);
List<Person> result = typedQuery.getResultList();
我看不到
Person.picture
的代理,但始终是实际的 Picture
对象。我还可以在生成的 SQL 中看到,为 JOIN
表创建了 Picture
。
但是当我进行一些连接时,EntityGraph 被接受并经过验证,但由于某些原因未应用:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<DepartmentMember> root = criteriaQuery.from(DepartmentMember.class);
Join<DepartmentMember, Person> person = root.join("member", JoinType.INNER);
Join<DepartmentMember, Department> department = root.join("department", JoinType.INNER);
criteriaQuery.where(criteriaBuilder.equals(department.get("name"), "development"));
criteriaQuery.select(person);
TypedQuery<Person> typedQuery = this.entityManager.createQuery(query);
EntityGraph<Person> entityGraph = entityManager.createEntityGraph(Person.class);
entityGraph.addAttributeNodes("picture");
query.setHint("javax.persistence.loadgraph", entityGraph);
List<Person> result = typedQuery.getResultList();
我得到
Person
实体始终为 Person.picture
设置代理。在生成的 SQL 查询中,我只看到我定义的 JOIN,但没有其他的。 EntityGraph 绝对是经过验证的,因为如果我添加一些不存在的属性,整个事情就会抛出错误。
我尝试了使用
fetch
连接的不同方法 - 这是有效的。喜欢:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<DepartmentMember> root = criteriaQuery.from(DepartmentMember.class);
Join<DepartmentMember, Person> person = root.join("member", JoinType.INNER);
person.fetch("picture");
Join<DepartmentMember, Department> department = root.join("department", JoinType.INNER);
criteriaQuery.where(criteriaBuilder.equals(department.get("name"), "development"));
criteriaQuery.select(person);
TypedQuery<Person> typedQuery = this.entityManager.createQuery(query);
List<Person> result = typedQuery.getResultList();
在这里我可以在生成的 SQL 中看到一个
JOIN
并且 Person.picture
没有代理,而是实际的对象。
有人知道使用连接时 EntityGraph 不起作用的原因是什么吗?我使用 EntityGraph 的方法有什么问题吗?
经过多次反复之后 - 由于 Spring 5 + Hibernate 6.6 的工作方式与 Spring 6 和 Hibernate 6 不同 - 我终于能够建立一个小型的概念验证应用程序。不幸的是,我不得不说
EntityGraph
按预期工作,不需要 fetch-join。我可以在创建的 SQL 语句中看到它正确插入了 LEFT JOIN
,而且我没有获得 Person.picture
的代理对象。所以我认为这只是最新的 Hibernate 5 版本中的一个错误 - 它可能永远不会得到修复。 😩