views:

49

answers:

1

Hello

I am using the Spring MVC framework with Hibernate. All of my controllers are using OpenSessionInViewInterceptor.

I am getting "could not initialize proxy - the owning Session was closed" errors in my controller's onSubmit() method. I believe this is because Hibernate needs to go back to the database to fetch certain objects which were retrieved as proxies, and the OpenSessionInViewInterceptor has already closed the session.

I have been working around these problems by using HibernateTemplate().reattach() on the objects.

My questions are:

a) am I right in my diagnosis? and b) is there a better way to re-open the Hibernate session? Is there a way to programmatically re-open a session in Hibernate without reattach()?

Edit: stack trace is below: when I iterate over the Set in my submit method I get the error

Data access failure: failed to lazily initialize a collection of role: com.companyname.apps.manager.domain.PriceChangeset.priceChanges, no session or session was closed

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.companyname.apps.manager.domain.PriceChangeset.priceChanges, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
    at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:163)
    **at com.companyname.apps.manager.service.impl.PriceChangesetServiceImpl.addChangesToSqlTransfer(PriceChangesetServiceImpl.java:263)
    at com.companyname.apps.manager.service.impl.PriceChangesetServiceImpl.approve(PriceChangesetServiceImpl.java:185)**
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:299)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:139)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy100.approve(Unknown Source)
    at com.companyname.apps.manager.webapp.controller.pricechanges.PriceChangeDetailsController.onSubmit(PriceChangeDetailsController.java:115)

Thanks!

+1  A: 

OpenSessionInViewInterceptor is designed to hold the session open for the duration of a single request. It is not designed to keep sessions open across multiple requests. Indeed, doing such a thing is strongly discouraged. Sessions should be released once the request is complete.

If you're trying to re-attach a Hibernate object to a new session, as part of a new request, then you need to use something like reattach(), merge(), etc, on the Hibernate Session or EntitymManager. OpenSessionInViewInterceptor won't help you out here.

skaffman