带有查询子属性的jpa实体图

时间:2014-11-04 00:31:09

标签: hibernate jpa jpa-2.1

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

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

我的作者类看起来像这样

@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>();
....

Book没有对作者的引用,所以它看起来像这样

@Entity
public class Book extends GenericEntity {
...

Generic Entity类只具有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类,并且热切地加载books属性,因为它在实体图中指定但在这种情况下books属性是延迟加载并抛出LazyInitialziation异常。 相反,如果我在作者的where子句(例如select a from Author a where a.id = 1)上使用了一个属性,那么它可以正常工作并急切地加载books属性。

任何想法都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

我遇到了与 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.