Question

I'm developing a Java project with Visual Paradigm which I am required to use. Visual Paradigm is using Hibernate. My project was running fine until I've added Genady RMI. I'm also required to use RMI.

In the server side I've got MainDb which manages all the querys to the database and in the client side I've got UserWindow and AdminWindow classes which implements RMI Remote. Theses two classes get the object MainDb through RMI.

When I'm running the server and the client, I've got an exception related to Lazy initialization with the error "no session or session was closed":

failed to lazily initialize a collection of role: dcl.UsuarioRegistrado.ORM_TieneVideosFavoritos, no session or session was closed.

As far as I know, Hibernate is using a different session from which the dcl.UsuarioRegistrado object was created. The problem is that I'm not managing sessions because the class PersistentManager only provides getSession(). The class PersistentManager is the class provided by VisualParadigm to manage Hibernate.

I've tried configuring all the entitiies to lazy="false" but the result has been worse because properties from some entities were not loaded correctly. For instance an object "Topic" was loaded with the String property "TopicName" to null.

So, what could I do to maintain the same session?

Thanks in advance and I'm very sorry but my poor English. It's difficult for me to explain the situation in English so, again, thanks.

Was it helpful?

Solution

This is a common problem. When you have a collection in an entity, Hibernate will inject a "Hibernate-aware" collection in the instance. So instead of a List, you get something which remembers the current session ("current" = the session in which the entity was loaded).

The reason for this is that session == database transaction. If Hibernate would load related entities using a new session, then you could see new rows, updated rows or you could get errors because rows have been deleted which still existed when you loaded the parent entity. It would be a mess.

To make sure this doesn't happen, Hibernate will use the original session to load all related entities. But code usually works differently. In one part, you load the entity. Session is closed. Then, in a completely unrelated part, you try to load children -> error.

There are three solutions:

  1. Disable lazy loading. This often doesn't work (loads too much, too slow). But it shouldn't cause errors; there might be a bug lurking in your code.

  2. When you load the entity, get the first entity from each collection. That will properly initialize the collection. The advantage here is that you can decide in your code when to load related instances and when to use rely on Hibernate for lazy loading.

    You can also only load those relations which you need; so this often solve the issues in the previous point. The drawback is that you need to know how other code will use your entity in advance. This is often hard or even impossible.

  3. You can create a new session and "attach" existing objects to this new session using Session.refresh(). Note that you need to be careful here; if you mix refreshed and old objects, you will get errors.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top