Hello all,
Sorry, I know, about LazyInitializationException was already written a lot in this forum.
I had my own experiences with this Exception and finally found a solution that might be also interesting for other users, and therefore I would like to discuss and to share it here.
I'm developping a web application that works on lot of data from database, which I want to cache in the web application's session context.
We use spring and JSF on top of hibernate. And I'm using the spring OpenSessionInViewFilter to automatically open a session for each request.
I use Lazy Fetching a lot to avoid bulk loading of the complete data into the session context, however consequently have faced the problem of LazyInitializationExceptio , accessing lazy loaded objects via getter methods in different requests.
I think that is quite a common problem. However I consider the generally proposed solutions
- load everything in advance, or
- load everything anew for each request
not very helpful, because they are foiling the lazy loading approach, are hard to handle or quite inefficient.
After several hours of googling I found a solution that proposed some workaround by checking the lazy initialization status explicitely (
Sorry, I lost the link, otherwise I would cite it here). I extended the solution and slimlined it.
In the following code is an example:
- I first check, whether the (proxied) object is correctly initialized.
- If not, (most propably, because it was initialized in a different Hibernate session) I cast it to a HibernateProxy and set it explicitely to the current hibernate session context.
Getting the current session needs some wizzardry to access spring hibernateTemplate. However it should be straightforward to get the hibernate session in other setups.
Code:
@ManyToOne(optional=false, fetch=FetchType.LAZY, cascade={CascadeType.DETACH})
public InstitutsData getKontaktSparkasse() {
if(!Hibernate.isInitialized(kontaktSparkasse)) {
if(kontaktSparkasse == null) return null;
if (kontaktSparkasse instanceof HibernateProxy) {
HibernateProxy proxiedInstitute = (HibernateProxy) kontaktSparkasse;
logger.info("Associating kontaktSparkasse to new session: " + kontaktSparkasse.getBLZ());
if (hibernateTemplate == null) {
ApplicationContext springApplicationContext = ApplicationContextProvider.getSpringApplicationContext();
hibernateTemplate = (HibernateTemplate) springApplicationContext.getBean("hibernateTemplate");
}
Session sess = hibernateTemplate.getSessionFactory().getCurrentSession();
proxiedInstitute.getHibernateLazyInitializer().setSession((SessionImplementor) sess);
}
}
return kontaktSparkasse;
So my questions are:
Is this a valid approach to deal with LazyInitializationExceptions?
I have to adapt every lazy getterMethod in my Data Model. Is there potentially an easier approach? (I think I could use Spring AOP, however I would like to avoid to open another dimension of complexity).
Thank you for your kind support.
Wallenstein