This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

Problem with HibernateTemplate.load

Sep 23rd, 2004, 09:00 PM

It turns out that Hibernate can return a proxy if you call Session.load. This means getHibernateTemplate.load can also return a proxy. It is not fun to access that returned proxy since the session (of course) is generally closed when the call returns.

I presume you are talking about getting back an object which contains a proxy on a lazy loaded association.

Note that you should generally be using HibernateTemplate inside a wrapping transaction, via something like HibernateTransactinManager (or JTATransactionManager+optionally HibernateInterceptor), which will ensure that there is in fact only one session used for the lifetime of the entire transaction. During the transaction, you can then navigate all lazy relationships without issues. If you need lazy relationships to be able to be navigated even later, just touch them before you leave the transaction to force a load, or alternately you could use something like the OpenSessionInView filter.

There is a large amount of documentation and samples on Hibernate, and other forum posts on this topic, so please take a look at that for more info...

Comment

I presume you are talking about getting back an object which contains a proxy on a lazy loaded association.

No, I am talking about the object returned from the load call is a proxy, not an associated object within the returned object. According to Hibernate documentation (and my testing) a call to Session.load can return either the object or a proxy for the object. In the case of returning a proxy HibernateTemplate.load returns the proxy, not the real object. You then, of course, can't use that proxy since the session may be closed already. - I understand wrapping the call in a transaction, but don't think that is supposed to be or should be a requirement in order to use the load method in HibernateTemplate. Do you agree?

Regards
Steve

Comment

All the template is doing w/regards to Session handling is convenience code, i.e. it will grab and use a pre-bound Session from the thread, and if that doesn't exist, and the allowCreate flag is set to true, will aslo create one, and in that case, if there is tx synchronizaiton active (i.e. you are in a transaction), then the new Session will actually be bound to the thread/tx as well, and not killed when the template is done.

In your case, if you want to work non-transactionally, you would have to use HibernateInterceptor to wrap your call graph (i.e. all the contained sequence of Hibernate-using code). I've been having a discussion with Juergen suggesting that even Hibernate Template itself should bind the Session to the thread even if there is no outer transaction, so you can do a programmatic equivalent of using HibernateInterceptor (i.e. somewhere you have one outer HibernateTemplate use, wrapping a bunch of contained HibernateTemplate calls), but he doesn't necessarilly agree that it's appropriate. In any case, HibernateInterceptor will work fine.

Comment

Thank you Colin, I have already detemined a way to work around this problem. I just don't use HibernateTemplate.load and wrote my own version that ensures the persistent instance is returned rather then a proxy.

I understand the load function as convienence code, but think it is not consistent with other methods in HibernateTemplate. That is, you have a call, in this case, that only works if you manage the session outside of HibernateTemplate.

I would like to suggest either deprecating this particular call, or having the implementation ensure a proxy is not returned.

Thanks again
Steve

PS

You wrote:

suggesting that even Hibernate Template itself should bind the Session to the thread even if there is no outer transaction, so you can do a programmatic equivalent of using HibernateInterceptor (i.e. somewhere you have one outer HibernateTemplate use, wrapping a bunch of contained HibernateTemplate calls)

I am WAY not experienced enough with Spring to have an opinion on this, and I appreciate all the thought you guys have put into this framework. I think you are making and will continue to make a huge difference in the java software world.