30

I've got an error that looks like this:

Could not initialize proxy - no Session

I'm working with java, hibernate and spring. This error comes up when trying to generate a PDF document, and I'm following the next steps to generate it on the fly and store in the database.

  1. I sent a request to the app through a POST method. This generates the PDF on the fly and shows to the user.

  2. Just after that request I send another, but through an ajax a request. This will generate the same PDF but will save it in the DB.

The error shows that a query could not be executed due to "could not initialize proxy - no Session" error.

Is there something that am I doing wrong, calling the same methods twice from the same user session? Could it be that the session is closed before both requests have finished?

Hope someone can help me to understand what is happening.

Misael P
  • 367
  • 1
  • 3
  • 10
  • Error aside, why would you make two distinct calls to create the PDF? Do it once, persist it, then retrieve it from the database instead. – Makoto May 25 '13 at 19:01
  • When I was writing the question I thought the same you are suggesting. But I wanted that someone with a bit more experience confirm the same. And just to make it more useful... Can you explain why the "could not initialize proxy - no Session" error happens in this specifi scenario?. thanks in advance. – Misael P May 25 '13 at 19:08
  • Hibernate issue. Show us the code behind the Ajax call so we can we can help you. – Jukka May 25 '13 at 20:18

1 Answers1

74

Your problem is that the hibernate Session lives only for one request. It opens in the start of the request and closes at the end. You guessed the answer: Hibernate session is closed before both requests are finished.

Exactly what is happening? Your entity objects live during both requests. How? They are stored in the HTTP session (which is a different thing called session) You don't give much information about the framework you are using, so I can't give you more details, but it is certain that the framework you are using somehow keeps your entities in the HTTP session. This is how the framework makes it easy for you to work with the same objects for more than one requests.

When the processing of the second request starts, the code is trying to access some entity (usually an element of a collection) that is lazily initialized by hibernate. The entity is not attached to a hibernate session, and so hibernate can't initialize the hibernate proxy before reading it. You should open a session and re-attach your entity to it at the beginning of the ajax request processing.

EDIT:

I will try to give a brief explanation of what is happening behind the scene. All java web frameworks have one or more servlets that handle the requests. The servlet handles each request (HttpRequest) by creating a new thread that will finally produce the response (HttpResponse). The method that processes each request is executed inside this thread.

At the beginning of the request processing your application should allocate the resources that it needs for processing (Transaction, Hibernate session etc). At the end of the processing cycle these resources are released (Transaction is committed, hibernate session is closed, JDBC connections are released etc). Lifecycle of these resources could be managed by your framework, or could be done by your code.

In order to support application state in a stateless protocol as HTTP, we have the HttpSession object. We (or the frameworks) put on HttpSession the information that remains relevant between different request cycles of the same client.

During the processing of the first request hibernate reads (lazily) an entity from the database. Due to lazy initialization some parts of this object's structure are hibernate proxy objects. These objects are associated with the hibernate session that created them.

The framework finds the entity from the previous request in the HttpSession object when you try to process the second request. Then it is trying to access a property from a child entity that was lazily initialized and now is a hibernate proxy object. The hibernate proxy object is an imitation of the real object that will ask its hibernate session to fill it with information from the database when someone tries to access one of its properties. This what your hibernate proxy is trying to do. But its session was closed at the end of the previous request processing, so now it doesn't have a hibernate session to use in order to be hydrated (filled with real info).

Note that it is possible that you have already opened a hibernate session at the beginning of the second request, but it isn't aware of the entity that contains the proxy object because this entity was read by a different hibernate sesion. You should re-attach the entity to the new hibernate session.

There is a lot of discussion about how to re-attach a detached entity, but the simplest approach right now is session.update(entity).

Hope it helps.

Devin Snyder
  • 142
  • 2
  • 10
nakosspy
  • 3,614
  • 1
  • 23
  • 30
  • Im using spring. So according to your answer the first request works with the information retrieved from the database using hibernate. Then the second request arrives and try to access to the same data executing a query that fails because the first request closed the hibernate session before the second request ends its job. Am I right? – Misael P May 25 '13 at 19:36
  • You got it. The same data you mention is the entity which exists in your user session (HttpSession). During the second request hibernate is trying to fill in the proxy object (which is an imitation of the real object) with information from the database. Before trying to execute the queries that will fetch data, hibernate tries to find the hibernate session object associated with this proxy object. But the proxy object is not associated with a hibernate session. The father entity of the proxy object was detached from session when the first request finished. – nakosspy May 25 '13 at 21:09
  • edited with some more details about the request processing cycles – nakosspy May 25 '13 at 21:43
  • I really appreciate your help. It gaves some lights about what my problem is and how to solve it. thanks! – Misael P May 25 '13 at 22:24
  • This is exactly the information I needed, and explains exactly the behavior I am seeing. Thanks! – user1071914 Nov 04 '13 at 23:53