Связь «Многие ко многим» с одной и той же сущностью

#java #hibernate #jpa

#java #переход в спящий режим #jpa

Вопрос:

У меня есть User сущность, которая может быть Manager или Client , Manager может иметь много Clients и Client может иметь много Managers .

Я попытался отобразить User сущность следующим образом:

 
  @Id
  @GeneratedValue(strategy = AUTO)
  private UUID uuid;

  @ManyToMany
  @JoinTable(name = "managers_clients",
      joinColumns = {
          @JoinColumn(name = "clientUuid", referencedColumnName = "uuid", nullable = false)},
      inverseJoinColumns = {
          @JoinColumn(name = "managerUuid", referencedColumnName = "uuid", nullable = false)})
  private List<UserEntity> managers;


  @ManyToMany(mappedBy = "managers")
  private List<UserEntity> clients;
  

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

не удалось лениво инициализировать коллекцию role: com.company.domain.common.entities.UserEntity.managers, не удалось инициализировать прокси-сервер — нет сеанса

Может кто-нибудь объяснить, почему это происходит и как я могу преодолеть эту проблему? Большое спасибо!

Комментарии:

1. Похоже, вы пытаетесь получить коллекцию с отложенной загрузкой после закрытия сеанса. В этой статье о Baeldung содержится больше информации. Быстрым решением было бы быстро извлечь коллекцию ( @ManyToMany(fetch = FetchType.EAGER) ), но это повлияло бы на все запросы к этой сущности, поскольку все manager s всегда извлекаются. Правильным способом было бы получить доступ к collectoin в момент времени, когда сеанс все еще открыт (т. Е. В @Transactional методе).

2. @Turing85 как реализовать @Transactional метод?

3. @Transactional является аннотацией CDI. Вы просто комментируете метод с его помощью. Остальное выполняется с помощью JPA и контейнера CDI (контейнер CDI создаст прокси-объект, который оборачивает фактическую реализацию и добавляет код для запуска и фиксации транзакций в транзакционных методах). Я бы рекомендовал руководство по JavaEE для получения дополнительной информации.

Ответ №1:

Проблема в том, что у вас нет сеанса во время выборки данных. Я не уверен, откуда вы извлекаете данные, но попробуйте добавить @Transactional к этому методу.

Это гарантирует, что JPA использует сеанс для получения данных.