Я столкнулся со столь обсуждаемым ""
Я работаю над приложением весенней загрузки, используя спящий режим.
Насколько я знаю, если атрибут объекта помечен как FetchType.LAZY, необходимо иметь сеанс Hibernate, чтобы иметь возможность инициировать соответствующий запрос для получения связанного объекта.
Ниже приведен метод, который извлекает список сущностей из родительской сущности:
@Transactional
public List<Portfolio> getSharedPortfolios(String userName){
User user = userService.getUserActive(userName);
List<Portfolio> sharedPortfolios = user.getSharedPortfolios();
//logger.debug("Number of Shared Portfolios: " + sharedPortfolios.size()); <======
return sharedPortfolios;
}
Метод getSharedPortfolios вызывается из контроллера и получает «org.hibernate.LazyInitializationException», а затем пытается получить доступ к этому списку (PersistentBag)
Поскольку метод getSharedPortfolios аннотирован аннотацией @Transactional, я ожидал, что при выполнении user.getSharedPortfolios() (sharedPortfolios — это список отложенной выборки) соответствующий список инициализируется. Но этого не происходит.
Может кто-нибудь объяснить мне, почему? И почему, если я раскомментирую строку журнала, которая печатает размер этого PersistentBag, исключение не выдается?
Нужно ли мне в этом случае явно инициализировать его с помощью EntityManager?
Большое спасибо.
Когда вы вызываете List<Portfolio> sharedPortfolios = user.getSharedPortfolios();, значение, присвоенное sharedPortfolios, является ленивым прокси.
Если вы просто вернете sharedPortfolios и получите доступ к нему вне вашего метода @Transactional, вы получите LazyInitializationException
С другой стороны, если вы обращаетесь к sharedPortfolios в своем методе @Transactional, происходит инициализация, и вы возвращаете уже инициализированные данные.
ИМХО то, что вы описываете, является ожидаемым поведением.
Существует несколько способов принудительного извлечения:
В качестве альтернативы проверьте настройку
spring.jpa.open-in-view=true
я не уверен, что это значит
"The getSharedPortfolios method is being called from a controller"
так что это может быть не ваш случай, но аннотация @Transactional не будет работать, если вы вызываете метод getSharedPortfolios из другого метода в том же классе.