【问题标题】:jpa entity graph with query on child attribute带有子属性查询的jpa实体图
【发布时间】:2014-12-30 19:00:39
【问题描述】:

我正在使用 jpa 2.1 EntityGraphs 来修改不同的 jpa 查询,在某些情况下,EntityGraphs 无法按预期工作。我正在努力的简单用例是

作者作为与 Book 子类具有单向一对多关系的父类,我想检索给定书名的作者结果,例如 findAllAuthorsByBookName。

我的 Author 类看起来像这样

@Entity
@NamedEntityGraph(name = "graph.author.detail", attributeNodes = {
        @NamedAttributeNode("books")
})
public class Author extends GenericEntity {

    @OneToMany
    @JoinColumn(name="author_id")
    private Set<Book> books = new HashSet<Book>();
....

这本书没有返回作者的引用,所以它看起来像这样

@Entity
public class Book extends GenericEntity {
...

通用实体类只具有 id 和 name 属性。

这是我查询数据的方式。

EntityGraph graph = em.getEntityGraph("graph.author.detail");       
Author author = (Author) em.createQuery("select a from Author a left join a.books b where b.name = 'book 1'")
                            .setHint("javax.persistence.loadgraph", graph).getResultList().get(0);

这不起作用。我期望 Author 类返回时会急切加载书籍属性,因为它在实体图中指定,但在这种情况下,书籍属性是延迟加载的并引发 LazyInitialzation 异常。 相反,如果我在 where 子句中使用作者的属性(例如select a from Author a where a.id = 1),那么它可以正常工作并急切地加载书籍属性。

任何想法都将不胜感激。

【问题讨论】:

    标签: hibernate jpa jpa-2.1


    【解决方案1】:

    我在 JPA 2.1/Hibernate 中遇到了类似的情况。我相信这可能是因为您已经必须在查询中加入书籍集合,Hibernate 忽略了EntityGraph 提示。您可以做的最好的事情是在查询中添加'left join fetch'。不仅仅是'left join'.

    需要注意的一点是,在我看来,您真正想要的查询是这样的:

    "select a from Author a where exists (select 1 from Book b where b.authorId = a.id and b.name = 'book 1')"
    

    这将返回所有拥有名为'book 1' 的书的作者。 EntityGraph hint 现在可能会正常工作,并且您的结果中不会出现重复作者。

    此外,上面的查询假设您至少将 author_id 列映射到 Author 和 Book 实体中的一个字段,如果不只是建立双向关系(在这种情况下它是 replace b.authorId = a.authorId with b.author = a.

    【讨论】:

      猜你喜欢
      • 2016-08-17
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-03
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      相关资源
      最近更新 更多