【问题标题】:How to fetch a association on the other side of a ManyToMany?如何获取多对多另一端的关联?
【发布时间】:2020-11-24 17:16:34
【问题描述】:

我有以下模型:“经典”多对多书籍/作者关联,但有两个特点。

  1. 作者与图书没有关联。
  2. 作者个人数据存储在其他关联实体上,称为 Person。

型号:

public class Book {
   @ManyToMany
   List<Author> authors;
}

public class Author {
    @OneToOne
    Person person;
}

public class Person {
    String name;
}

我想编写一个服务,给定一本书,它将返回与之相关的所有作者。我还想检索避免 N+1 问题的个人数据。

在我的书库中,我写了一个这样的自定义查询:

@Query("select b.authors from Book b join b.authors a join fetch a.person where b = :book")
List<Author> listAuthors(@Param("book") Book book);

但我有以下错误:

查询指定连接抓取,但是抓取的所有者 选择列表中不存在关联 (...)

我可以通过在 Author 端添加与 Books 的关联并从中获取 Person 来解决这个问题。不幸的是,就我而言,作者不了解书籍是非常可取的。

有没有办法从 Book 中获取 Person 数据?

【问题讨论】:

    标签: spring spring-data-jpa


    【解决方案1】:

    我使用 EXISTS 子句解决了它:

    @Query("select a from Author a join fetch a.person " + 
           "where exists (select 1 from Book b where b = :book and a member of b.authors)")
    List<Author> listAuthors(@Param("book") Book book);
    

    【讨论】:

      【解决方案2】:

      这实际上是一个 Hibernate 错误HHH-14116 - 我最近偶然发现了一个相关的错误,并且在 Hibernate Chat 的讨论中也提交了这个错误。已经有a fix,但是AFAIK还没有发布。

      避免这种情况的一种方法是让关系是双向的,并从作者端进行查询。 否则,您可以使用子查询来完成,但我不确定这是否适用于 Spring Data JPA:

      select a from Author a join fetch a.person where a.id in
          (select a.id from Book b join b.authors a where b = :book)
      

      【讨论】:

        【解决方案3】:

        您是否也尝试使用 @Query 选择 Person?

        @Query("select b.authors, a.person from Book b join b.authors a join fetch a.person where b = :book")
        List<Author> listAuthors(@Param("book") Book book);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-17
          • 1970-01-01
          • 2021-10-07
          • 1970-01-01
          • 2017-11-06
          • 2013-03-02
          • 2010-09-18
          • 2017-02-14
          相关资源
          最近更新 更多