Announcement Announcement Module
Collapse
No announcement yet.
Illegal attempt to associate a collection with two open sess 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 sess

    Hi everyone:

    I want to save and update two object in one method.I use the code:
    Code:
    public boolean insertArticle(Article a, User u){
    		boolean  obj_id = false;
    		
    	
    			User user=null;
    			Object o=null;
    			try {
    				o = this.getHibernateTemplate().createQuery(this.getSession(),
    						"from User u where u.userName='" + u.getUserName() + "'")
    						.uniqueResult();
    			} catch (HibernateException e2) {
    				// TODO Auto-generated catch block
    				e2.printStackTrace();
    			}
    			if(null!=o){
    				user=(User)o;
    			}
    			a.setUser(user);
    			Set articleSet=user.getArticleSet();
    			
    			if(null!=articleSet){
    				articleSet.add(a);
    			}else{
    				articleSet=new HashSet();
    				articleSet.add(a);
    			}
    			user.setArticleSet(articleSet);
    			
    			try {
    				
    				//Object id=this.getHibernateTemplate().save(a);
    				//log.info("Saving id: "+id);
    				
    				this.getHibernateTemplate().update(user);
    				obj_id=true;
    			} catch (DataAccessResourceFailureException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}  catch (IllegalStateException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    But I get a Exception:
    Code:
    org.springframework.orm.hibernate.HibernateSystemException: Illegal attempt to a
    ssociate a collection with two open sessions; nested exception is net.sf.hiberna
    te.HibernateException: Illegal attempt to associate a collection with two open s
    essions
    net.sf.hibernate.HibernateException: Illegal attempt to associate a collection w
    ith two open sessions
            at net.sf.hibernate.collection.PersistentCollection.setCurrentSession(Pe
    rsistentCollection.java:257)
            at net.sf.hibernate.impl.OnUpdateVisitor.processCollection(OnUpdateVisit
    or.java:38)
            at net.sf.hibernate.impl.AbstractVisitor.processValue(AbstractVisitor.ja
    va:69)
            at net.sf.hibernate.impl.AbstractVisitor.processValues(AbstractVisitor.j
    ava:36)
            at net.sf.hibernate.impl.AbstractVisitor.process(AbstractVisitor.java:93
    )
            at net.sf.hibernate.impl.SessionImpl.doUpdateMutable(SessionImpl.java:14
    56)
            at net.sf.hibernate.impl.SessionImpl.doUpdate(SessionImpl.java:1470)
            at net.sf.hibernate.impl.SessionImpl.update(SessionImpl.java:1355)
            at org.springframework.orm.hibernate.HibernateTemplate$15.doInHibernate(
    HibernateTemplate.java:339)
            at org.springframework.orm.hibernate.HibernateTemplate.execute(Hibernate
    Template.java:176)
            at org.springframework.orm.hibernate.HibernateTemplate.update(HibernateT
    emplate.java:336)
            at lyo.hotmail.site.service.ForumDAOImpl.insertArticle(ForumDAOImpl.java
    :139)
            at lyo.hotmail.site.action.PostArticleController.handleRequest(PostArtic
    leController.java:74)
            at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.ha
    ndle(SimpleControllerHandlerAdapter.java:44)
            at org.springframework.web.servlet.DispatcherServlet.doService(Dispatche
    rServlet.java:495)
            at org.springframework.web.servlet.FrameworkServlet.service(FrameworkSer
    vlet.java:321)
            at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
    icationFilterChain.java:237)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
    ilterChain.java:157)
            at lyo.hotmail.site.util.HiberFilter.doFilter(HiberFilter.java:50)
            at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
    icationFilterChain.java:186)
            at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
    ilterChain.java:157)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
    alve.java:214)
            at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
    eContext.java:104)
            at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
    a:520)
            at org.apache.catalina.core.StandardContextValve.invokeInternal(Standard
    ContextValve.java:198)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
    alve.java:152)
            at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
    eContext.java:104)
            at org.apache.catalina.authenticator.AuthenticatorBase.invoke(Authentica
    torBase.java:462)
            at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
    eContext.java:102)
            at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
    a:520)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
    ava:137)
            at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
    eContext.java:104)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
    ava:118)
            at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
    eContext.java:102)
            at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
    a:520)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
    ve.java:109)
            at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
    eContext.java:104)
            at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
    a:520)
            at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
    
            at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:16
    0)
            at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
    :799)
            at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
    ssConnection(Http11Protocol.java:705)
            at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java
    :577)
            at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP
    ool.java:684)
            at java.lang.Thread.run(Thread.java:534)
    I config transaction in my config file,it is:
    Code:
    <bean id="MyDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <!-- results in a setDriverClassName&#40;String&#41; call -->
            <property name="driverClassName">
                <value>com.mysql.jdbc.Driver</value>
            </property>
            <property name="url">
                <value>jdbc&#58;mysql&#58;//127.0.0.1&#58;3306/Hibernate?useUnicode=true&amp;characterEncoding=gb2312</value>
            </property>
            <property name="username">
                <value>root</value>
            </property>
    		<property name="password">
                <value>root</value>
            </property>
    		
    		<property name="defaultAutoCommit"> 
                <value>false</value> 
            </property>
    		
        </bean>
    	<!--
    <bean id="MyJNDIDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
      <property name="jndiName">
        <value>jdbc/mysql</value>
      </property>
    </bean>
    -->
    <bean id="MySessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
       <property name="mappingResources">
          <list>
            <value>lyo/hotmail/site/bean/Article.hbm.xml</value>
            <value>lyo/hotmail/site/bean/Forum.hbm.xml</value>
            <value>lyo/hotmail/site/bean/Message.hbm.xml</value>
            <value>lyo/hotmail/site/bean/User.hbm.xml</value>
            <value>lyo/hotmail/site/bean/UserDetail.hbm.xml</value>
          </list>
       </property>
       <property name="hibernateProperties">
          <props>
            <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.query.substitutions">true=1 false=0</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.use_outer_join">false</prop>
          </props>
       </property>
       <property name="dataSource"><ref bean="MyDataSource"/></property>
    </bean>
    
    <bean id="myTransactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
      <property name="sessionFactory">
        <ref bean="MySessionFactory"/>
      </property>
    </bean>
    <bean id="myProductService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
      <property name="transactionManager">
        <ref bean="myTransactionManager"/>
      </property>
      <property name="target">
        <ref bean="formDao"/>
      </property>
      <property name="transactionAttributes">
        <props>
          <prop key="insert*">PROPAGATION_REQUIRED</prop>
          <!--<prop key="someOtherBusinessMethod">PROPAGATION_MANDATORY</prop>-->
        </props>
      </property>
    </bean>
    
    
    <bean id="fproxy" class="lyo.hotmail.site.util.ForumProxy">
       <property name="fdao">
          <ref bean="formDao"/>
       </property>
    </bean>
    <bean id="viewSpringForumController" class="lyo.hotmail.site.action.ViewForumcontroller">
    <property name="forumProxy">
         <ref bean="fproxy"/>
    </property>
       </bean>
       <bean id="rewriteURLController" class="lyo.hotmail.site.action.DispatchForumController">
    <property name="fdao">
          <ref bean="formDao"/>
       </property>
       </bean>
    <bean id="postArticleController" class="lyo.hotmail.site.action.PostArticleController">
    <property name="fdao">
          <ref bean="formDao"/>
       </property>
    </bean>
    <bean id="viewDetailController" class="lyo.hotmail.site.action.viewDetailController">
    <property name="forumProxy">
         <ref bean="fproxy"/>
    </property>
    </bean>
        <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="/oldForum.spring">viewSpringForumController</prop>
    				<prop key="/viewForum.spring">viewSpringForumController</prop>
    				<prop key="/detail.spring">viewDetailController</prop>
    				<prop key="/newPost.spring">rewriteURLController</prop>
    				<prop key="/post.spring">postArticleController</prop>
                </props>
            </property>
       
        </bean>
    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
            <property name="prefix"><value>/WEB-INF/forum/</value></property>
            <property name="suffix"><value>.jsp</value></property>
        </bean>
    <bean id="formDao" class="lyo.hotmail.site.service.ForumDAOImpl">
       <property name="sessionFactory">
          <ref bean="MySessionFactory"/>
       </property>
       <property name="udao">
          <ref bean="userDao"/>
       </property>
    </bean> 
     <bean id="userDao" class="lyo.hotmail.site.service.UserDAOImpl">
       <property name="sessionFactory">
          <ref bean="MySessionFactory"/>
       </property>
    </bean>
    What's wrong with my code? Does I open two sessions in my code? Help

  • #2


    I change my code to this,it don't throws any Exception,But no data insert into database. ;-(

    Code:
    public boolean insertArticle&#40;Article a,User u&#41; &#123;
    		Session s = null;
    		Transaction t = null;
    		boolean  obj_id = false;
    		
    		s=this.getSession&#40;&#41;;
    			User user=null;
    			Object o=null;
    			try &#123;
    				o = s.createQuery&#40;
    						"from User u where u.userName='" + u.getUserName&#40;&#41; + "'"&#41;
    						.uniqueResult&#40;&#41;;
    			&#125; catch &#40;HibernateException e2&#41; &#123;
    				// TODO Auto-generated catch block
    				e2.printStackTrace&#40;&#41;;
    			&#125;
    			if&#40;null!=o&#41;&#123;
    				user=&#40;User&#41;o;
    			&#125;
    			a.setUser&#40;user&#41;;
    			Set articleSet=user.getArticleSet&#40;&#41;;
    			
    			if&#40;null!=articleSet&#41;&#123;
    				articleSet.add&#40;a&#41;;
    			&#125;else&#123;
    				articleSet=new HashSet&#40;&#41;;
    				articleSet.add&#40;a&#41;;
    			&#125;
    			user.setArticleSet&#40;articleSet&#41;;
    			
    			try &#123;
    				
    								
    				s.update&#40;user&#41;;
    				obj_id=true;
    			&#125; catch &#40;DataAccessResourceFailureException e&#41; &#123;
    				// TODO Auto-generated catch block
    				e.printStackTrace&#40;&#41;;
    			&#125;  catch &#40;IllegalStateException e&#41; &#123;
    				// TODO Auto-generated catch block
    				e.printStackTrace&#40;&#41;;
    			&#125; catch &#40;HibernateException e&#41; &#123;
    				// TODO Auto-generated catch block
    				e.printStackTrace&#40;&#41;;
    			&#125; finally&#123;
    				try &#123;
    					s.close&#40;&#41;;
    				&#125; catch &#40;HibernateException e1&#41; &#123;
    					// TODO Auto-generated catch block
    					e1.printStackTrace&#40;&#41;;
    				&#125;
    			&#125;
    			
    		
    		return obj_id;
    
    	&#125;
    Why

    Comment


    • #3
      Replace the createQuery method with the find method on HibernateTemplate and don't use that getSession() method.

      Comment


      • #4


        Originally posted by tentacle
        Replace the createQuery method with the find method on HibernateTemplate and don't use that getSession() method.
        But createQuery can use "uniqueResult ()" method.This method is very convinent if I want to get only one object. If I don't do it in this way . My code will be much more,For example:

        Code:
        List articles=this.getHibernateTemplate&#40;&#41;.find&#40;"from Article a ,User u where a.user.id=u.id"&#41;;
        Article article=&#40;Article&#41;articles.get&#40;0&#41;;
        ..........................................
        I don't want to do this in this hard way. I also want to know why this Exception happen

        Comment


        • #5
          I don't want to do this in this hard way. I also want to know why this Exception happen
          It's hard to say exactly way the exception occurs because I haven't seen all the code of your dao. The exception probably occurs because you do a query with one session (which you get from the getSession method) and you update the user object with another session.

          I'm not sure this is the real problem but for arguments sake I suppose it is. To resolve this you can do a number of things. For convenience you could set the one-to-many relationship (set tag) between user and article to cascade="save-update" and the many-to-one relationship (if present - the many-to-one tag) to cascade="none".

          Next it depends if article is transient of detached. If it's transient it's ok to set the user on a and add a to the article set on user. User is a persistent object because you retrieved it through a query. If the session remains open - which I suppose is the case - you do not need to explicitly update user. This update is probably what is causing you problems.

          About the getSession method: don't do it. It depends how you get the session but I guess you call sessionFactory.openSession(). The problem here is that the session is not managed by HibernateTemplate which is probably not what you want. HibernateTemplate is there to help us so we should you is as much as possible. Instead of managing sessions yourself try using the callback mechanism in HibernateTemplate:

          Code:
          String queryString = "from .....";
          o = getHibernateTemplate&#40;&#41;.execute&#40;
          new HibernateCallback&#40;&#41; &#123;
            public Object doInHibernate&#40;Session session&#41; throws HibernateException &#123;
              Query queryObject = createQuery&#40;session, queryString&#41;;
              return queryObject.uniqueResult&#40;&#41;;
            &#125;
          &#125;&#41;;
          Maybe it would be useful for you to get a copy of J2EE Development without EJB by Rod Johnson and Juergen Hoeller. Chapter 10 explains why it's important to use HibernateTemplate.

          Comment


          • #6


            Thks for your reply. It don't throw Exception if I use HibernateCallback,But no data was inserted too.

            Tomcat console output is :
            Code:
            00&#58;08&#58;36,323  INFO Configuration&#58;1116 - instantiating and configuring caches
            00&#58;08&#58;36,323  INFO SessionFactoryImpl&#58;118 - building session factory
            00&#58;08&#58;36,403  INFO SessionFactoryObjectFactory&#58;82 - Not binding factory to JNDI,
             no JNDI name configured
            00&#58;08&#58;46,587  INFO PropertyMessageResources&#58;127 - Initializing, config='org.apac
            he.struts.actions.LocalStrings', returnNull=true
            00&#58;08&#58;46,607  INFO SQLErrorCodesFactory&#58;197 - Looking up default SQLErrorCodes f
            or DataSource
            00&#58;08&#58;46,607  INFO SQLErrorCodesFactory&#58;202 - Database product name found in cac
            he for DataSource &#91;org.apache.commons.dbcp.BasicDataSource@130c132&#93;. Name is 'My
            SQL'.
            Hibernate&#58; select user0_.USER_ID as USER_ID0_, user0_.USER_GRADE as USER_GRADE0_
            , user0_.USER_NAME as USER_NAME0_, user0_.USER_PASSWORD as USER_PAS4_0_ from use
            r user0_ where user0_.USER_ID=?
            Hibernate&#58; select messageset0_.USER_ID as USER_ID__, messageset0_.MESSAGE_ID as
            MESSAGE_ID__, messageset0_.MESSAGE_ID as MESSAGE_ID0_, messageset0_.MESSAGE_CONT
            ENT as MESSAGE_2_0_, messageset0_.MESSAGE_TITLE as MESSAGE_3_0_, messageset0_.SE
            ND_TIME as SEND_TIME0_, messageset0_.SENDER as SENDER0_, messageset0_.USER_ID as
             USER_ID0_ from message messageset0_ where messageset0_.USER_ID=?
            Hibernate&#58; insert into message &#40;MESSAGE_CONTENT, MESSAGE_TITLE, SEND_TIME, SENDE
            R, USER_ID, MESSAGE_ID&#41; values &#40;?, ?, ?, ?, ?, ?&#41;
            It indeed have insert sql,But why no data was inserted into database?
            It is very strange! Does someone come across this problem?

            Comment


            • #7
              It indeed have insert sql,But why no data was inserted into database?
              It is very strange! Does someone come across this problem?
              The insert statement is for the message table but if I understand correctly the problem you experience is that no article is inserted. Is this correct?

              Comment


              • #8


                Originally posted by tentacle
                It indeed have insert sql,But why no data was inserted into database?
                It is very strange! Does someone come across this problem?
                The insert statement is for the message table but if I understand correctly the problem you experience is that no article is inserted. Is this correct?
                Sorry, This is another test . I think it maybe environment problem,So I change my tables and do another test. The new test table is called message.

                Comment

                Working...
                X