How to Fix Org.Hibernate.Lazyinitializationexception - Could Not Initialize Proxy - No Session

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:

  1. Leave it as it is, being aware that you must not access lazy loaded properties.

  2. Make sure a transaction is started before the converters get invoked.

  3. 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



Leave a reply



Submit