Невозможно инициализировать загруженные отношения внутри метода `@ Transactional` - PullRequest
1 голос
/ 11 апреля 2019

У меня есть набор простых моделей, подобных этой (для краткости геттеры и сеттеры опущены):

@Entity
public class Customer {
  @Id 
  private Integer id;
}

@Entity
public class Order {
  @Id
  private Integer id;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "customer_id")
  private Customer customer;
}

Я пытаюсь загрузить ордер с помощью репозитория Spring JPA с методом findById, включая заказчика.

Сначала я попробовал это:

@Transactional
Optional<Order> findById(Integer id) {
    return repository.findById(id);
}

Но когда я попытался получить доступ к клиенту, я получил исключение LazyInitializationException: не удалось инициализировать прокси-сервер - нет сеанса.Поэтому после обращения к некоторым другим вопросам я обновил свой метод, сделав его немного уродливее, но явно вызвав Hibernate.initialize:

@Transactional
Optional<Order> findById(Integer id) {
    return repository.findById(id)
                     .map( order -> {
                         Hibernate.initialize(order.getCustomer());
                         return order;
                     );
}

Но я все еще получаю org.hibernate.LazyInitializationException: could not initialize proxy - no Session.repository является обычным CrudRepository , который предоставляет готовый метод findById.

Как я могу инициализировать этот лениво загруженный дочерний объект? Насколько я понимаю, @Transactional указывает, что я все еще должен быть в транзакции для полного вызова этого метода.Единственное, что находится ниже по течению, - это сам репозиторий, который является просто интерфейсом, поэтому я не уверен, как еще можно заставить загрузку этого дочернего объекта.

Сущность Order и все остальное в нейправильно извлечены из базы данных;только когда я пытаюсь получить загруженные ленивыми дочерними объектами, у нас начинают возникать проблемы.

Единственный способ, которым мне удалось получить эту работу, - это написать пользовательский метод hql в репозитории.используя left join fetch.Хотя это работает, оно загромождает мой репозиторий с помощью метода, который в значительной степени дублирует другой, и который, я уверен, мне на самом деле не нужен (поэтому я бы предпочел не делать этого таким образом).

Spring-Boot 2.1.4.RELEASE, Spring 5.1.6.RELEASE, Hibernate 5.3.7.Final.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...