Spring 如何在多个网络的另一端获取关联?

Spring 如何在多个网络的另一端获取关联?,spring,spring-data-jpa,Spring,Spring Data Jpa,我有以下模型:一个经典的多对多书籍/作者协会,但有两个特点 作者与书籍没有关联。 作者个人数据存储在其他关联实体(称为Person)上。 模型: public class Book { @ManyToMany List<Author> authors; } public class Author { @OneToOne Person person; } public class Person { String name; } 我想写一个服务,

我有以下模型:一个经典的多对多书籍/作者协会,但有两个特点

作者与书籍没有关联。 作者个人数据存储在其他关联实体(称为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);
但我有以下错误:

查询指定的联接获取,但获取的联接的所有者 选择列表中不存在关联

我可以通过在作者一方的书籍中添加关联并从中提取人员来解决这个问题。不幸的是,在我的例子中,作者不了解书籍是非常可取的


有没有办法从书中获取人物数据?

您是否也尝试过使用@Query选择人物

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

您是否也尝试过使用@Query选择人员

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

这实际上是一个Hibernate Bug——我最近偶然发现了一个相关的Bug,在Hibernate聊天中的讨论中,这个Bug也被归档了。已经有了,但恐怕还没有发布

避免这种情况的一种方法是使关系具有双向性,并从作者方面进行查询。 否则,您可以使用子查询来完成,但我不确定这是否适用于Spring数据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)

这实际上是一个Hibernate Bug——我最近偶然发现了一个相关的Bug,在Hibernate聊天中的讨论中,这个Bug也被归档了。已经有了,但恐怕还没有发布

避免这种情况的一种方法是使关系具有双向性,并从作者方面进行查询。 否则,您可以使用子查询来完成,但我不确定这是否适用于Spring数据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)

我用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);

我用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);