Class LazyInitializationExceptionIndicates an attempt to access not-yet-fetched data outside of a session context. For example, when an uninitialized proxy or collection is accessed after the session was closed.
Just make the lazy=false and hibernate will load the child when parent is loaded from the database. In the above configuration. If lazy="false" : - when you load the Employee object that time child object Address is also loaded and set to setAddresss() method. If you call employee.
Hibernate 4.1.6 finally solves this issue: https://hibernate.atlassian.net/browse/HHH-7457
You need to set the hibernate-property hibernate.enable_lazy_load_no_trans=true
Here's how to do it in Spring:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="packagesToScan" value="com.mycompany.somepackage"/>
<property name="jpaVendorAdapter" ref="hibernateVendorAdapter"/>
<property name="jpaDialect" ref="jpaDialect"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.enable_lazy_load_no_trans">true</prop>
</props>
</property>
</bean>
Voila; Now you don't have to worry about LazyInitializationException while navigating your domain-model outside of a hibernate-session (persistence-context in "JPA-speak")
There are many ways to pre-fetch properties, so they are there after session is closed:
JOIN FETCH
keyword.Several problems may occur when you try these solutions:
JOIN FETCH
may be linked through multiple 'many' relationships involving List's. In this case the resulting query returns ambiguous results and Hibernate will refuse to fetch your data in a single query.The best way to go is to try a JOIN FETCH
first. If that doesn't work try the getter approach. If that gets messed up at runtime by the JIT compiler, assign the result to a public static volatile Object
.
Or stop using Hibernate...
Note that you shouldn't use hibernate.enable_lazy_load_no_trans
pre Hibernate 4.1.7, as it leaks connections. See https://hibernate.onjira.com/browse/HHH-7524
LazyInitializationException means that you are calling the collection after the hibernate session has closed, or after the object has been detached from the session.
You need to either re-attach the object to hibernate session, change the place where you are calling the collection, or move the boundary of where the session gets closed to a higher layer.
The best way to solve the LazyInitializationException is to use the JOIN FETCH directive in your entity queries.
FetchType.EAGER loading is bad for performance. Also, there are anti-patterns such as:
hibernate.enable_lazy_load_no_trans
Which you should never use since they either require the database connection to be open for the UI rendering (Open Session in View), or a database connection is needed for every lazy association that is fetched outside of the initial Persistence Context (hibernate.enable_lazy_load_no_trans
).
Sometimes, you don't even need entities, and a DTO projection is even better. You should fetch entities only when you need to modify them. For read-only transactions, DTO projections are better.
OpenSessionInView is one pattern to deal with this problem. Some info here:
http://www.hibernate.org/43.html
You'll want to be cautious when implementing this pattern and understand the implications. Each time you navigate a lazy association in the view it will fire off another SQL query to load the data. If your use cases are such that the number and size of these SQL queries is small then this may not matter. Make sure that at a minimum you adjust your logging settings so you can see what kind of queries Hibernate is "magically" executing in the background for you to load the data.
Also consider the kind of application you are writing. If you're not dealing with remoting (no web services, no AJAX-based web client) then OSIV may work very nicely. However, if a remoting serializer starts to walk the entire object graph, it will likely trigger a ridiculous number of SQL queries and cripple your DB and app server.
When you are using collection and you want to initialize it with lazy loading then use that collection before session close. If session is close after that if you want to use then you get lazyinitializeException because lazy is try by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With