Announcement Announcement Module
Collapse
No announcement yet.
Hibernate two open sessions problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate two open sessions problem

    hi
    i use hibenate 3.2.2 and Spring 2.5 in my project.
    in my code when i was remove an object from DB i get this exception
    org.springframework.orm.hibernate3.HibernateSystem Exception: 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

    applicationContext.xml :
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotati on.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation" value="classpath:hibernate.cfg.xml"/>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
    <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
    <prop key="flushMode">AUTO</prop>
    </props>
    </property>
    </bean>


    <bean id="transactionManager" class="org.springframework.orm.hibernate3.Hibernat eTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="nestedTransactionAllowed" value="true"/>
    </bean>

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.Hibernat eTemplate">
    <property name="sessionFactory" ref="sessionFactory"/>
    </bean>



    <!-- UniversalDao - can be used when doing standard CRUD - made available
    'fooDao' below. -->
    <bean id="universalDao" class="com.navaco.dao.hibernate.UniversalDaoHibern ate">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="hibernateTemplate" ref="hibernateTemplate"/>
    </bean>


    <aop:config>
    <aopointcut id="managerTx" expression="execution(* *..service.imp.*(..))"/>
    <aop:advisor
    pointcut-ref="managerTx"
    advice-ref="managerTxAdvice"
    />

    </aop:config>

    <tx:advice id="managerTxAdvice" transaction-manager="transactionManager">
    <tx:attributes>
    <tx:method
    name="*"
    read-only="false"
    propagation="REQUIRED"
    isolation="READ_UNCOMMITTED"
    rollback-for="Exception"
    />
    </tx:attributes>
    </tx:advice>
    <tx:annotation-driven transaction-manager="transactionManager"/>




    <bean id="openSessionInView" class="org.springframework.orm.hibernate3.support. OpenSessionInViewFilter">
    <property name="sessionFactoryBeanName" value="sessionFactory"/>
    <property name="flushMode" value="AUTO"/>
    <property name="singleSession" value="false"/>
    </bean>

    <bean id="manager"
    class="com.navaco.service.impl.UniversalManagerImp l">
    <property name="dao" ref="universalDao"/>
    </bean>

    class="com.navaco.service.baseinf.OrganizationChar tManagerImp"
    parent="manager"/>
    Hibernate :

    <class name="OrganizationChart" table="ORGANIZATION_CHARTS">
    <id name="id" column="ORG_ID" type="integer">
    <generator class="increment"/>
    </id>
    <property name="name" column="ORG_NAME" type="string"/>
    <many-to-one name="parent" cascade="none">
    <column name="ORG_PARENT_ID" not-null="false"/>
    </many-to-one>
    <set name="children" cascade="all-delete-orphan" inverse="true" lazy="true" batch-size="10">
    <key column="ORG_ID"/>
    <one-to-many class="OrganizationChart" not-found="ignore"/>
    </set>
    </class>
    and code :
    OrganizationChartManagerImp manager = (OrganizationChartManagerImp) getSpringBean(BeansConstant.ORGANIZATION_CHART_MAN AGER);
    OrganizationChart oc = (OrganizationChart) manager.get(OrganizationChart.class, 1);
    getHibernateTemplate().delete(oc);

  • #2
    Hi everyone
    I think solve that problem . i just remove
    <bean id="openSessionInView" class="org.springframework.orm.hibernate3.support. OpenSessionInViewFilter">
    <property name="sessionFactoryBeanName" value="sessionFactory"/>
    <property name="flushMode" value="AUTO"/>
    <property name="singleSession" value="false"/>
    </bean>
    from my application context and web.xml and it works but i get the following exception :
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.navaco.model.OrganizationChart.children, no session or session was closed

    please help me
    Last edited by sadyou; Jan 4th, 2009, 04:41 AM.

    Comment


    • #3
      I am newbe in Spring+Hibernate, but it seems that everybody comes across this situation, and every thread ends with "Still it doesn't work"! So for collection, you either get lazily initialization, or two open sessions exception, and there is no way out!

      Finally I found a solution that saved me, though it is not an answeer to your question... For my project I am having service layer, that is between control layer and DAO, I use lazy loading and no OpenSessionInView filter. In service layer methods I get required object using DAO, then initialize object fields that I need for exactly this service, including fields that are collections. I have class Issue, IssueComment and Issue has List of issue comments. Mapping for Issue -

      <hibernate-mapping>
      <class name="com.rustelematics.model.Issue" table="ISSUE" schema="BUGTRACKER">
      <id name="cid" type="java.lang.Long">
      <column name="CID" precision="8" scale="0" />
      <generator class="increment" />
      </id>
      <many-to-one name="status" class="com.rustelematics.model.Status" fetch="select" lazy="proxy">
      <column name="CSTATUS" precision="2" scale="0" not-null="true" />
      </many-to-one>
      <many-to-one name="clientType" class="com.rustelematics.model.ClientType" fetch="select" lazy="proxy">
      <column name="CCLIENT" precision="1" scale="0" not-null="true" />
      </many-to-one>
      <many-to-one name="submitter" class="com.rustelematics.model.Submitter" fetch="select" lazy="proxy">
      <column name="CSUBMITTERID" precision="8" scale="0" not-null="true" />
      </many-to-one>
      <many-to-one name="app" class="com.rustelematics.model.App" fetch="select" lazy="proxy">
      <column name="CAPP" precision="5" scale="0" not-null="true" />
      </many-to-one>
      <property name="cshortdescription" type="java.lang.String">
      <column name="CSHORTDESCRIPTION" length="128" not-null="true" />
      </property>
      <property name="cfulldescription" type="com.rustelematics.model.usertypes.StringClob TypeUsingTempTable">
      <column name="CFULLDESCRIPTION" />
      </property>
      <property name="cdate" type="java.util.Date">
      <column name="CDATE" length="7" not-null="true" />
      </property>
      <property name="clasteditdate" type="java.util.Date">
      <column name="CLASTEDITDATE" length="7" not-null="true" />
      </property>
      <bag name="comments" cascade="all" lazy="true" order-by="CDATE asc">
      <key column="CISSUE"/>
      <one-to-many class="com.rustelematics.model.IssueComment" />
      </bag>
      </class>
      </hibernate-mapping>

      And Issue controllers call IssueServiceImpl methods.
      To retrieve list of issues and display main issue fields in list I have method -

      public List getIssueList() {
      List<Issue> issueList = issueDAO.findAll();
      Iterator<Issue> it = issueList.iterator();
      while (it.hasNext()) {
      Issue issue = (Issue)it.next();
      getHibernateTemplate().refresh(issue);
      getHibernateTemplate().initialize(issue.getStatus( ));
      getHibernateTemplate().initialize(issue.getSubmitt er());
      getHibernateTemplate().initialize(issue.getClientT ype());
      }
      return issueList;
      }

      To display all issue data, incuding iteration through its comments -

      public Issue getAllIssueData(String cid) {
      Issue issue = issueDAO.findById(cid);
      getHibernateTemplate().refresh(issue);
      getHibernateTemplate().initialize(issue.getApp());
      getHibernateTemplate().initialize(issue.getClientT ype());
      getHibernateTemplate().initialize(issue.getStatus( ));
      getHibernateTemplate().initialize(issue.getSubmitt er());
      getHibernateTemplate().initialize(issue.getComment s());
      return issue;
      }

      Than I am calling methods from IssueService interface that IssueServiceImpl implements. Here is IssueService bean declaration from applicationContext -

      <bean id="IssueService" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
      <property name="target">
      <bean class="com.rustelematics.service.IssueServiceImpl" >
      <property name="issueDAO" ref="IssueDAO" />
      <property name="hibernateTemplate">
      <ref bean="hibernateTemplate"/>
      </property>
      </bean>
      </property>
      <property name="transactionManager">
      <ref bean="transactionManager"/>
      </property>
      <property name="transactionAttributes">
      <props>
      <prop key="*">PROPAGATION_REQUIRED</prop>
      </props>
      </property>
      </bean>

      Hope this helps, but still I wonder if there are better ways to deal with collection fields and awoid both lazily initialization, and two open sessions exception...

      Comment

      Working...
      X