Как получить ассоциацию на другой стороне ManyToMany? - PullRequest
0 голосов
/ 04 августа 2020

У меня следующая модель: «классическая» ассоциация «многие ко многим» книга / автор, но с двумя особенностями.

  1. Автор не имеет связи с книгами.
  2. Персональные данные автора хранятся в другом связанном объекте, называемом Person.

Модель:

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

public class Author {
    @OneToOne
    Person person;
}

public class Person {
    String name;
}

Я хотел бы написать сервис, который, учитывая книгу, будет вернуть всех авторов, связанных с ним. Я также хотел бы получить личные данные, избегая проблемы N + 1.

В моем репозитории Book я написал собственный запрос вроде этого:

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

Но у меня следующая ошибка:

запрос определил получение соединения, но владелец выбранной ассоциации не присутствовал в списке выбора (...)

Мне удалось решить эту проблему, добавив ассоциация с книгами на стороне автора и извлечение из нее человека. К сожалению, в моем случае очень желательно, чтобы Авторы не знали о Книгах.

Есть ли способ получить данные Человека из Книги?

Ответы [ 3 ]

2 голосов
/ 04 августа 2020

На самом деле это ошибка Hibernate. HHH-14116 - Недавно я наткнулся на связанную ошибку, и в обсуждении в чате Hibernate эта ошибка тоже была указана. Уже существует исправление , но, 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)
0 голосов
/ 05 августа 2020

Я решил это с помощью предложения 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);
0 голосов
/ 04 августа 2020

Пробовали ли вы также выбрать человека с помощью @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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...