title: Spring transaction management breaks hibernate cascade
body: <p>I'm having a problem where the addition of spring's transaction management to an application causes Hibernate to throw the following error:</p>
  
  <pre><code>org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: org.fstrf.masterpk.domain.ReportCriteriaBean.treatmentArms
  org.hibernate.engine.Collections.processDereferencedCollection(Collections.java:96)
  org.hibernate.engine.Collections.processUnreachableCollection(Collections.java:39)
  org.hibernate.event.def.AbstractFlushingEventListener.flushCollections(AbstractFlushingEventListener.java:218)
  org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:77)
  org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
  org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
  org.springframework.orm.hibernate3.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:135)
  org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:72)
  org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:905)
  org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:715)
  org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
  org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
  org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
  org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
  org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
  $Proxy92.saveNewReportCriteria(Unknown Source)
  org.fstrf.masterpk.domain.logic.MasterPkFacade.saveNewReportCriteria(MasterPkFacade.java:134)
  org.fstrf.masterpk.controllers.ReportCriteriaController.setupReportType(ReportCriteriaController.java:302)
  sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  java.lang.reflect.Method.invoke(Method.java:585)
  org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:413)
  org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:134)
  org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:310)
  org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:297)
  org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
  org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
  org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
  org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
  javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
  org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
  </code></pre>
  
  <p>I'm using Spring 2.5 and annotations to implement this management. Here is the class containing the saveNewReportCriteria method (which, as can be seen by the stack trace, is causing the error)</p>
  
  <pre><code>@Transactional(
       propagation = Propagation.REQUIRED,
       isolation = Isolation.DEFAULT,
       readOnly = false)
  public class HibernateReportCriteriaDao implements ReportCriteriaDao{
  
  private HibernateTemplate hibernateTemplate;
  
  public Integer saveNewReportCriteria(ReportCriteriaBean reportCriteria) {
      hibernateTemplate.save(reportCriteria);
  
      List&lt;Integer&gt; maxIdList = hibernateTemplate.find("SELECT max(id) from ReportCriteriaBean");
          logger.info("ID of newly saved list is: " + maxIdList.get(0));
          return maxIdList.get(0);
      }
  
      public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
          this.hibernateTemplate = hibernateTemplate;
      }
  }
  </code></pre>
  
  <p>Then I added the following sections to my configuration files to tell spring that I am using annotation driven transaction management:</p>
  
  <pre><code>&lt;bean id="actgDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"&gt;
      &lt;property name="jndiName" value="jdbc/actg" /&gt;
      &lt;property name="resourceRef" value="true" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
      &lt;property name="dataSource" ref="actgDataSource" /&gt;
  &lt;/bean&gt;
  
  &lt;tx:annotation-driven/&gt;
  </code></pre>
  
  <p>I'm pretty sure that the de-referencing error is being caused due to the proxy class that Spring AOP creates and uses in order to handle transaction management, but I have no idea how I'd go about fixing it.</p>