How to fix org.hibernate.LazyInitializationException - could not initialize proxy - no Session
What is wrong here is that your session management configuration is set to close session when you commit transaction. Check if you have something like:
<property name="current_session_context_class">thread</property>
in your configuration.
In order to overcome this problem you could change the configuration of session factory or open another session and only than ask for those lazy loaded objects. But what I would suggest here is to initialize this lazy collection in getModelByModelGroup itself and call:
Hibernate.initialize(subProcessModel.getElement());
when you are still in active session.
And one last thing. A friendly advice. You have something like this in your method:
for (Model m : modelList) {
if (m.getModelType().getId() == 3) {
model = m;
break;
}
}
Please insted of this code just filter those models with type id equal to 3 in the query statement just couple of lines above.
Some more reading:
session factory configuration
problem with closed session
how to address org.hibernate.LazyInitializationException: could not initialize proxy - no Session with Spring controllers that use Converters
The immediate problem comes from the use of userRepository.getOne(userId)
. It is implemented in the SimpleJpaRepository
using EntityManager.getReference
. This method returns just a Proxy, which only contains its id. And only when a property gets accessed those get lazy loaded. This includes simple properties like name
in your case.
The immediate fix is to use findOne
which should load all the eager properties of your entity which should include simple properties, so the exception goes away.
Note that this will slightly change the behavior of your converter. The current version will not fail when the id is not existent in the database because it never checks. The new one will obtain an empty Optional and you'll have to convert it to null or throw an exception.
But there is (or might be) a bigger problem hiding: The entity is still detached because in absence of an explicit transaction demarcation the transactions only span single repository calls. So if you later want to access lazy loaded properties, you might get the same problem again. I see various options to consider:
Leave it as it is, being aware that you must not access lazy loaded properties.
Make sure a transaction is started before the converters get invoked.
Mark your controllers with
@Transactional
and loading the user (again) in the controller.
LazyInitializationException in Hibernate : could not initialize proxy - no Session
Here's a good reference to get you familiar with how .get() and .load() method works.
@Override
public Product getProductById(int id) {
Product p = sessionFactory.getCurrentSession().load(Product.class, id);
return p;
}
session.load()
by default returns a proxy object without hitting a database. It basically returns NoObjectFoundError
if there aren't any records on the table or else it will return a reference without populating the actual object or even hitting the database.
Your above method returns a proxy and since it has to initialize the your object as well, the session remains open and object is populated.
@Override
public Product getProductById(int id) {
return sessionFactory.getCurrentSession().load(Product.class, id);
}
But in your second method, basically a proxy is returned without any initialization. session is closed thereafter without any prior use. Thus you get the error.
Hope that helps
LazyInitializationException - could not initialize proxy - no Session
I would recommend one of the following approaches:
1) In you repository method findProjectEmployeesWithinDates
you can do
for (ProjectEmployee pe : listProjectEmployees)
{
pe.getEmployee().getPerson();
}
so it will initialize objects while session is open
2) You can fetch data using query
SELECT * FROM ProjectEmployee pe JOIN FETCH pe.employee e JOIN FETCH e.person
In this way Hibernates will populate execution result with employee and person objects automatically
org.hibernate.LazyInitializationException: could not initialize proxy - no Session?
Try to add @Transactional
to the validate method:
@Override
@Transactional(readOnly=true)
public void validate(Object target, Errors errors) {
...
}
What happens is that because there is no @Transactional
annotation, there is no session associated to the method, and each query will run in it's own session that is closed immediately afterwards.
The method session.load()
always returns a proxy, unlike session.get()
(see here for differences between load vs get).
So the proxy is returned, but due to the missing @Transactional
the session that created the proxy is immediately closed. When the proxy is accessed the first time, it's session is closed so we get the 'no session' error.
If you change from load()
to get()
that will only partially solve the problem, because if after the get you try to load for example a lazy initialized collection, the exception occurs again.
Adding @Transactional
to the business method will ensure the presence of the same session for the duration of the method call, and prevent the occurrence of this and other related errors.
Related Topics
How to Map a Composite Key with JPA and Hibernate
Why Is Java's Simpledateformat Not Thread-Safe
How to Use Try-With-Resources with Jdbc
Number of Days Between Two Dates in Joda-Time
How to Wire One Pane to Another
Display Indeterminate Jprogressbar While Batch File Runs
Jformattedtextfield Is Not Properly Cleared
Difference in Days Between Two Dates in Java
Simple Http Server in Java Using Only Java Se API
How to Use Java Property Files
How to Deal with a Slow Securerandom Generator
How to Solve Javax.Net.Ssl.Sslhandshakeexception Error
What Is the "Continue" Keyword and How Does It Work in Java
Java 8: Difference Between Two Localdatetime in Multiple Units
Why Does Ssl Handshake Give 'Could Not Generate Dh Keypair' Exception
Encode Base64 Cannot Find Symbol Error
How to Perform Mouseover Function in Selenium Webdriver Using Java