Announcement Announcement Module
Collapse
No announcement yet.
Illegal attempt to associate a collection with two open sessions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Illegal attempt to associate a collection with two open sessions

    Hello there! in a previous post: [http://forum.springframework.org/sho...d.php?t=26780] I've said that I've solved this problem. I was wrong
    This is a big post, but I've tried to post everything I judged to be necessary to ask for help


    I have a web app using OSIVF pattern provided by Spring (removed it later the problem persists, but thought was important to mention)

    Here's the configuration of my service:

    Code:
    <bean id="votacaoService"		class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    		<property name="target">
    			<bean
    				class="VotacaoServiceImpl">
    				<property name="votacaoDAO">
    					<ref bean="votacaoDAO" />
    				</property>
    				<property name="eleitorDAO">
    					<ref bean="eleitorDAO" />
    				</property>
    			</bean>
    		</property>
    		<property name="proxyInterfaces">
    			<list>
    				<value>VotacaoService</value>
    			</list>
    		</property>
    		<property name="transactionAttributes">
    			<props>
    				<prop key="autenticar*">PROPAGATION_SUPPORTS,readOnly</prop>
    				<prop key="emFaseVotacao">PROPAGATION_SUPPORTS,readOnly</prop>
    				<prop key="buscar*">PROPAGATION_SUPPORTS,readOnly</prop>
    				<prop key="apurarVotos">PROPAGATION_SUPPORTS,readOnly</prop>
    				<prop key="cadastrar*">PROPAGATION_REQUIRED</prop>				
    			</props>
    		</property>
    		<property name="transactionManager">
    			<ref bean="transactionManager"/>
    		</property>
    	</bean>
    ean>
    Ok, my DAOs exnteds HibernateDAOSupport.

    Well, my flow is:
    An struts action is called. It's superclass calls a method on this service that is a readOnly method (emFaseVotacao).
    The action then do the following:

    Code:
    		VotacaoService votacaoService = (VotacaoService)getWebApplicationContext().getBean("votacaoService");
    		ObraService obraService = (ObraService)getWebApplicationContext().getBean("obraService");
    		Obra obra = obraService.obterObra(Long.valueOf(registrarVotoForm.getObra()));
    		Votante votante = (Votante)request.getSession().getAttribute("votante");
    		votacaoService.cadastrarVoto(votante,obra);
    So as you can see I call another service (ObraService) that just do a findByPK on the database (readOnly) then I call the cadastrarVoto (the PROPAGATION_REQUIRED method)

    Well everything was in portuguese, but that this method do is add a vote to a voter (votante)
    Code:
     <set
                name="votos"
                lazy="false"
                inverse="true"
                cascade="all"
                sort="unsorted"
            >
    
                <key
                    column="ID_VOTANTE"
                >
                </key>
    
                <one-to-many
                      class="*.*.*.*.Voto"
                />
    
            </set>
    So when I try to save the entity I get the error:
    Code:
    org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
    Any help would come in hand :P
    posting my log as reply (too long)

  • #2
    Code:
    [HttpRequestHandler-21448718] DefaultListableBeanFactory.getBean(189) | Returning cached instance of singleton bean 'votacaoService'
    [HttpRequestHandler-21448718] DefaultListableBeanFactory.getObjectForSharedInstance(810) | Bean with name 'votacaoService' is a factory bean
    [HttpRequestHandler-21448718] TransactionInterceptor.createTransactionIfNecessary(221) | Getting transaction for services.votacao.VotacaoService.emFaseVotacao
    [HttpRequestHandler-21448718] HibernateTransactionManager.getTransaction(253) | Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@fc7ceb]
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.initSynchronization(214) | Initializing transaction synchronization
    [HttpRequestHandler-21448718] TransactionInterceptor.doCommitTransactionAfterReturning(264) | Invoking commit for transaction on services.votacao.VotacaoService.emFaseVotacao
    [HttpRequestHandler-21448718] HibernateTransactionManager.triggerBeforeCommit(653) | Triggering beforeCommit synchronization
    [HttpRequestHandler-21448718] HibernateTransactionManager.triggerBeforeCompletion(669) | Triggering beforeCompletion synchronization
    [HttpRequestHandler-21448718] HibernateTransactionManager.triggerAfterCompletion(693) | Triggering afterCompletion synchronization
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.clearSynchronization(265) | Clearing transaction synchronization
    [HttpRequestHandler-21448718] DefaultListableBeanFactory.getBean(189) | Returning cached instance of singleton bean 'votacaoService'
    [HttpRequestHandler-21448718] DefaultListableBeanFactory.getObjectForSharedInstance(810) | Bean with name 'votacaoService' is a factory bean
    [HttpRequestHandler-21448718] DefaultListableBeanFactory.getBean(189) | Returning cached instance of singleton bean 'obraService'
    [HttpRequestHandler-21448718] DefaultListableBeanFactory.getObjectForSharedInstance(810) | Bean with name 'obraService' is a factory bean
    [HttpRequestHandler-21448718] TransactionInterceptor.createTransactionIfNecessary(221) | Getting transaction for services.obras.ObraService.obterObra
    [HttpRequestHandler-21448718] HibernateTransactionManager.getTransaction(253) | Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@f02db7]
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.initSynchronization(214) | Initializing transaction synchronization
    [HttpRequestHandler-21448718] SessionFactoryUtils.doGetSession(329) | Opening Hibernate Session
    [HttpRequestHandler-21448718] SessionFactoryUtils.doGetSession(337) | Registering Spring transaction synchronization for new Hibernate Session
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.bindResource(162) | Bound value [org.springframework.orm.hibernate3.SessionHolder@496381] for key [org.hibernate.impl.SessionFactoryImpl@c3a53b] to thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.getResource(137) | Retrieved value [org.springframework.orm.hibernate3.SessionHolder@496381] for key [org.hibernate.impl.SessionFactoryImpl@c3a53b] bound to thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] HibernateTemplate.execute(357) | Found thread-bound Session for HibernateTemplate
          06/07/11 15:21:54 Hibernate: select obra0_.id as id0_0_, obra0_.NOME as NOME0_0_, obra0_.LINK as LINK0_0_, obra0_.NUM_BAIRRO as NUM4_0_0_, obra0_.COD_ADM_REG as COD5_0_0_, obra0_.NUM_VOTOS as NUM6_0_0_ from OBRA obra0_ where obra0_.id=?
    [HttpRequestHandler-21448718] HibernateTemplate.execute(381) | Not closing pre-bound Hibernate Session after HibernateTemplate
    [HttpRequestHandler-21448718] TransactionInterceptor.doCommitTransactionAfterReturning(264) | Invoking commit for transaction on services.obras.ObraService.obterObra
    [HttpRequestHandler-21448718] HibernateTransactionManager.triggerBeforeCommit(653) | Triggering beforeCommit synchronization
    [HttpRequestHandler-21448718] HibernateTransactionManager.triggerBeforeCompletion(669) | Triggering beforeCompletion synchronization
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.unbindResource(185) | Removed value [org.springframework.orm.hibernate3.SessionHolder@496381] for key [org.hibernate.impl.SessionFactoryImpl@c3a53b] from thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] HibernateTransactionManager.triggerAfterCompletion(693) | Triggering afterCompletion synchronization
    [HttpRequestHandler-21448718] SessionFactoryUtils.doClose(785) | Closing Hibernate Session
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.clearSynchronization(265) | Clearing transaction synchronization
    [HttpRequestHandler-21448718] TransactionInterceptor.createTransactionIfNecessary(221) | Getting transaction for services.votacao.VotacaoService.cadastrarVoto
    [HttpRequestHandler-21448718] HibernateTransactionManager.getTransaction(253) | Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@2d14a]
    [HttpRequestHandler-21448718] HibernateTransactionManager.getTransaction(280) | Creating new transaction with name [services.votacao.VotacaoService.cadastrarVoto]
    [HttpRequestHandler-21448718] HibernateTransactionManager.doBegin(449) | Opened new Session [org.hibernate.impl.SessionImpl@1304ef4] for Hibernate transaction
    [HttpRequestHandler-21448718] HibernateTransactionManager.doBegin(479) | Not preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@1304ef4]
    [HttpRequestHandler-21448718] HibernateTransactionManager.doBegin(534) | Exposing Hibernate transaction as JDBC transaction [org.apache.commons.dbcp.PoolableConnection@17469af]
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.bindResource(162) | Bound value [org.springframework.jdbc.datasource.ConnectionHolder@1c69f7b] for key [org.apache.commons.dbcp.BasicDataSource@1c36f46] to thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.bindResource(162) | Bound value [org.springframework.orm.hibernate3.SessionHolder@110506e] for key [org.hibernate.impl.SessionFactoryImpl@c3a53b] to thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.initSynchronization(214) | Initializing transaction synchronization
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.getResource(137) | Retrieved value [org.springframework.orm.hibernate3.SessionHolder@110506e] for key [org.hibernate.impl.SessionFactoryImpl@c3a53b] bound to thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.getResource(137) | Retrieved value [org.springframework.orm.hibernate3.SessionHolder@110506e] for key [org.hibernate.impl.SessionFactoryImpl@c3a53b] bound to thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] HibernateTemplate.execute(357) | Found thread-bound Session for HibernateTemplate
    [HttpRequestHandler-21448718] HibernateTemplate.execute(381) | Not closing pre-bound Hibernate Session after HibernateTemplate
    [HttpRequestHandler-21448718] RuleBasedTransactionAttribute.rollbackOn(119) | Applying rules to determine whether transaction should rollback on org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
    [HttpRequestHandler-21448718] RuleBasedTransactionAttribute.rollbackOn(137) | Winning rollback rule is: null
    [HttpRequestHandler-21448718] RuleBasedTransactionAttribute.rollbackOn(143) | No relevant rollback rule found: applying superclass default
    [HttpRequestHandler-21448718] TransactionInterceptor.doCloseTransactionAfterThrowing(280) | Invoking rollback for transaction on services.votacao.VotacaoService.cadastrarVoto due to throwable [org.springframework.orm.hibernate3.HibernateSystemException: Illegal attempt to associate a collection with two open sessions; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions]
    [HttpRequestHandler-21448718] HibernateTransactionManager.triggerBeforeCompletion(669) | Triggering beforeCompletion synchronization
    [HttpRequestHandler-21448718] HibernateTransactionManager.processRollback(577) | Initiating transaction rollback
    [HttpRequestHandler-21448718] HibernateTransactionManager.doRollback(599) | Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@1304ef4]
    [HttpRequestHandler-21448718] HibernateTransactionManager.triggerAfterCompletion(693) | Triggering afterCompletion synchronization
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.clearSynchronization(265) | Clearing transaction synchronization
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.unbindResource(185) | Removed value [org.springframework.orm.hibernate3.SessionHolder@110506e] for key [org.hibernate.impl.SessionFactoryImpl@c3a53b] from thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] TransactionSynchronizationManager.unbindResource(185) | Removed value [org.springframework.jdbc.datasource.ConnectionHolder@1c69f7b] for key [org.apache.commons.dbcp.BasicDataSource@1c36f46] from thread [HttpRequestHandler-21448718]
    [HttpRequestHandler-21448718] HibernateTransactionManager.doCleanupAfterCompletion(659) | Closing Hibernate Session [org.hibernate.impl.SessionImpl@1304ef4] after transaction
    [HttpRequestHandler-21448718] SessionFactoryUtils.doClose(785) | Closing Hibernate Session

    Comment


    • #3
      The error is basically a feature/limitation of Hibernate (it's not something related to Spring in any way). One of the motivation behind it is that the collections are not versioned like objects so when the same collection is opened with multiple sessions HB doesn't know who's going to win.
      The only solution I can think of is to stop using the collection at the same time. In most cases the workaround is to use the active side of the relationship to do the updates instead of using the inactive side - i.e. if you have a parent with multiple children, do the update through the children and not through the parent since then you'll don't have to initialize the children collection.

      Comment


      • #4
        Thanks Constin. We found out that the error was neither spring or hibernate. It was a mistake made by one of our developers in an parent dao, instead of using getSession() he was using getHibernateTemplate().getSessionFactory().openSes sion(), causing two sessions to be opened at the same time.
        Best regards

        Comment


        • #5
          Issue in JUnit testing as well...

          This appears to be happening when extending AbstractTransactionalDataSourceSpringContextTests for JPA as well, with Hibernate as the underlying persistence manager. My unit tests run fine, until i try to delete.

          Stack trace:

          Code:
          org.springframework.orm.jpa.JpaSystemException: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions; nested exception is javax.persistence.PersistenceException: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
          Caused by: javax.persistence.PersistenceException: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
              at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:567)
              at org.hibernate.ejb.AbstractEntityManagerImpl.remove(AbstractEntityManagerImpl.java:225)
              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.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:150)
              at $Proxy28.remove(Unknown Source)
              at edu.harvard.mgh.lcs.inbox.dao.impl.GenericDaoJpaImpl.remove(GenericDaoJpaImpl.java:75)
              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:266)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
              at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor$PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationAdvisor.java:76)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
              at edu.harvard.mgh.lcs.dao.spring.FinderAnnotationIntroductionInterceptor.invoke(FinderAnnotationIntroductionInterceptor.java:37)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
              at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor$PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationAdvisor.java:76)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
              at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:209)
              at $Proxy32.remove(Unknown Source)
              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:266)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
              at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:100)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
              at edu.harvard.mgh.lcs.dao.spring.FinderAnnotationIntroductionInterceptor.invoke(FinderAnnotationIntroductionInterceptor.java:37)
              at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
              at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:209)
              at $Proxy34.remove(Unknown Source)
              at test.TestInboxUserDao.testRemove(TestInboxUserDao.java:69)
              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 junit.framework.TestCase.runTest(TestCase.java:154)
              at junit.framework.TestCase.runBare(TestCase.java:127)
              at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
              at junit.framework.TestResult$1.protect(TestResult.java:106)
              at junit.framework.TestResult.runProtected(TestResult.java:124)
              at junit.framework.TestResult.run(TestResult.java:109)
              at junit.framework.TestCase.run(TestCase.java:118)
              at junit.framework.TestSuite.runTest(TestSuite.java:208)
              at junit.framework.TestSuite.run(TestSuite.java:203)
              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
              at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
          Caused by: org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions
              at org.hibernate.collection.AbstractPersistentCollection.setCurrentSession(AbstractPersistentCollection.java:410)
              at org.hibernate.event.def.OnUpdateVisitor.processCollection(OnUpdateVisitor.java:40)
              at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:101)
              at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:61)
              at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:55)
              at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:123)
              at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:72)
              at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:768)
              at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:746)
              at org.hibernate.ejb.AbstractEntityManagerImpl.remove(AbstractEntityManagerImpl.java:219)
              ... 52 more
          Unit test code:
          Code:
              public void testRemove() {
                  InboxUser lInboxUser = mInboxUserDao.findByPrimaryKey(2);
                  mInboxUserDao.remove(lInboxUser);
                  
                  lInboxUser = mInboxUserDao.findByPrimaryKey(2);
                  assertNull(lInboxUser);
              }
          Last edited by ryannorris; Jul 18th, 2006, 11:01 AM.

          Comment


          • #6
            Found the problem - wrong transaction propogation for my findByPrimaryKey method. Needed to be @Transactional(propogation=Propogation.NOT_SUPPORT ED)

            Comment


            • #7
              The problem was with the Open Session In view filter mapping.
              It was creating a session on getSession
              And other on save.

              You can change only singleSession as false
              default its true

              Comment

              Working...
              X