当前位置: 首页 > 知识库问答 >
问题:

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

燕元明
2023-03-14

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

作者作为父类,与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>();
....

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

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

这不起作用。我希望返回的作者类带有急切加载的书籍属性,因为它在实体图中指定,但在这种情况下,书籍属性是延迟加载的,并抛出LazyLaunalziation异常。如果我在作者for where子句上使用一个属性(例如从作者中选择一个,其中a.id=1),那么它可以正常工作并急切加载书籍属性。

任何想法将不胜感激。

共有1个答案

鞠侯林
2023-03-14

我正在经历与JPA 2.1 / Hibernate类似的情况。我相信可能是因为您已经必须在查询中加入书籍集合 Hibernate 忽略了 EntityGraph 提示。您能做的最好的事情就是在查询中进行“左联接提取”。不仅仅是“左联接”。

需要注意的一点是,在我看来,您实际想要的查询是:

"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 提示现在可能会正常工作,并且您不会在结果中得到重复的作者。

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

 类似资料:
  • 声明使用输入参数属性作为查询参数的Spring data JPA查询的最简单方法是什么? ...但Spring data/JPA不喜欢我在参数上指定属性名。 最合适的选择是什么?

  • 我有一个使用Postgre 9.3和JPA2.1(Hibernate实现)的Spring MVC应用程序。我有一个类'电影',其中有一组评论。我想写一个JPA NamedQuery,它返回我所有的电影细节,但只有批准的评论。评论可以有其他状态,但我想只显示批准的评论。 我的班级如下所示: 我写的查询不会过滤评论并返回包含所有评论的电影;它的工作原理与上面显示的findMovieById查询相同。

  • 问题内容: 我有一个实体类和一个基于该实体的子类: 和 我需要发出仅在基类(A)上使用存储过程的本机查询。如果我尝试如下: 我收到有关“在ResultSet中未找到clazz_列”的错误。我假设JPA提供程序添加了此列,以便区分基类和扩展类。我可以通过显式添加clazz列和子类中的所有字段来解决此问题: 其中“ prop1”和“ prop2”是子类B的属性。但是,这似乎是不必要的修改,并且如果子类

  • 显然,扩展了,是抽象的,继承是, 和 具有 其他原因 。 但生成的SQL是这样的: 在我期待的时候: 请注意 使用另一根- 使用子查询- 将lastName字段上移到主题 使用本机查询 使用实体图 是不能接受的。 我感兴趣的是可以在WHERE子句中直接声明和使用的东西(仅从CriteriaBuilder和/或单个Root生成,就像子句一样)(如果确实存在的话)。

  • 我通常使用JPQL查询数据库,但今天我不得不使用原生查询,因为性能原因和JPQL中没有的特性(联接子查询)。使用JPQL,可以使用join fetch来检索父实体及其子实体集合。然而,当我尝试使用本机查询时,对于每个父实体,将返回多行,每行包含父实体及其子实体之一的数据。然后返回的列表包含父级的重复对象。假设一个父级有两个子级,那么下面的查询将在列表中返回2个父级,而不是1个。 任何人都知道如何避

  • 我正在尝试查询hibernate表中的RunEntity。查询中的第一个where子句搜索testName=传递值testName的RunEntities。在stacktrace中,它提到在RunEntity中找不到testname类型的匹配项,但是RunEntity对象显式地有一个名为testname的字符串,带有setter和getter以及@Column符号。 表格设置 查询 实体 stac