Reputation: 1001
I am facing the so much discussed ""
I'm working on a spring boot application using hibernate.
As far I know, if an attribute of an Entity is marked as FetchType.LAZY, with need to have a Hibernate session to be able to trigger the respective query to bring the related entity.
Following is a method that retrieves a List of entities from a parent entity:
@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;
}
The getSharedPortfolios method is being called from a controller and getting the "org.hibernate.LazyInitializationException" then try to access this List (PersistentBag)
Being getSharedPortfolios method annotated with the @Transactional annotation, i was expecting that when user.getSharedPortfolios() (sharedPortfolios is a Lazy Fetch List) is executed, the respective list is initialized. But is not happening that.
Can someone explain to me why? And Why if i uncomment the log line that prints the size of that PersistentBag, the exception is not thrown?
Do I need in this case explicitly initialise it using EntityManager?
Thank you so much.
Upvotes: 1
Views: 2269
Reputation: 82
I'm not sure what this means
"The getSharedPortfolios method is being called from a controller"
so this might not be your case but the @Transactional
annotation will not work if you are calling the getSharedPortfolios
method from another method within the same class.
Upvotes: 0
Reputation: 26066
When you call List<Portfolio> sharedPortfolios = user.getSharedPortfolios();
the value assigned to sharedPortfolios
is a lazy proxy.
If you simply return sharedPortfolios
and access it outside your @Transactional
method, you get LazyInitializationException
On the other hand, if you access sharedPortfolios
within your @Transactional
method, the initialization occurs, and you return already initialized data.
IMHO what you describe is expected behaviour.
There are multiple ways to force the fetch:
Alternatively, check the setting
spring.jpa.open-in-view=true
Upvotes: 2