У меня есть набор простых моделей, подобных этой (для краткости геттеры и сеттеры опущены):
@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.