Announcement Announcement Module
Collapse
No announcement yet.
Lazy Question Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Lazy Question

    Hi, probally my question is stupid, but i don't found the solution serching on forum and Spring docs...
    I'v a class A that is relationed to class B with n-n relation; with hibernate when i add an B instance to A i use this code:
    A a = (A)session.load(A.class,aId);
    B b = (B)session.load(B.class,bId);
    a.getBs().add(b);
    session.update(a);

    Now if i use Spring (HibernateDaoSupport for example) and try to realize the equivalent code:

    A a = (A) getHibernateTemplate().load(A.class,aId);
    B b = (B)getHibernateTemplate().load(B.class,bId);
    a.getBs().add(b);

    throws an Exception because the b collection is lazy loaded and the session is closed.

    I try to use HibernateCallback but the problem is same...
    Note this DAO is used by a SessionBean and i don't would that the session is always open for client request (ex. OpenSessionInView)

    Thanks in advance!
    Alessio

  • #2
    Set the logging mode for
    log4j.logger.org.springframework.orm.hibernate3.su pport=DEBUG and opensessioninviewfilter will log a message before opening and closing a session. In this way you can find out if your session has been closed.

    Comment


    • #3
      Ok i try it, thank for answer...

      Comment


      • #4
        Are both calls being performed in the scope of a transaction? See if this helps:

        http://forum.springframework.org/showthread.php?t=15705
        Last edited by robyn; May 16th, 2006, 05:02 AM.

        Comment


        • #5
          I don't use Programmatic Transaction Demarcation but Declarative Transaction Demarcation...
          For this example (A/B class ) my applicationContext.xml like this:

          <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverM anagerDataSource">
          <property name="driverClassName"><value>....</value></property>
          <property name="url"><value>....</value></property>
          <property name="username"><value>...</value></property>
          <property name="password"><value>...</value></property>
          </bean>

          <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSes sionFactoryBean">
          <property name="dataSource"><ref local="dataSource"/></property>
          <property name="mappingResources">
          <list>
          <value>mappings/A.hbm.xml</value>
          <value>mappings/B.hbm.xml</value>
          </list>
          </property>
          <property name="hibernateProperties">
          <props>
          <prop key="hibernate.dialect">.....t</prop>
          <prop key="hibernate.hbm2ddl.auto">update</prop>
          <prop key="hibernate.show_sql">true</prop>
          </props>
          </property>

          <property name="eventListeners">
          <map>
          <entry key="merge">
          <bean class="org.springframework.orm.hibernate3.support. IdTransferringMergeEventListener"/>
          </entry>
          </map>
          </property>
          </bean>

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


          <bean id="aTarget" class="tests.AServiceImp">
          <property name="sessionFactory"><ref local="sessionFactory"/></property>
          </bean>


          <bean id="aService" class="org.springframework.transaction.interceptor .TransactionProxyFactoryBean">
          <property name="transactionManager"><ref local="transactionManager"/></property>
          <property name="target"><ref local="aTarget"/></property>
          <property name="transactionAttributes">
          <props>
          <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
          <prop key="update*">PROPAGATION_REQUIRED</prop>
          <prop key="save*">PROPAGATION_REQUIRED</prop>
          <prop key="delete*">PROPAGATION_REQUIRED</prop>
          </props>
          </property>
          </bean>

          In this case i shold use the HibernateTemplate and not TransactionTemplate (if i understand the docs this is used only for Programmatic Transaction Demarcation), i missing anything in applicationContext.xml for leave the session open (for only methods of AService and not for all client request life)?

          Thanks

          Comment


          • #6
            I was having the same problem, then started using programatic transactions, and got it to work. I would like to get it to work using declarative. Please let me know if you find a solution.

            Comment


            • #7
              Ok, it's my conceptual error; i thinked that Springs (whit AOP) open the session at the start of any method declared on class that extends HibernateDaoSupport and closed it when method ends (or delegate the close of session to Hibernate like two properties hibernate.transaction.flush_before_completion and hibernate.transaction.auto_close_session from java code...); i thinked also that, because this, the getHibernateTemplate return a helper class for reduce the code (load, update, ecc.) but if i call two getHibernateTemplate (or more) in the same method that those shared the same session and this is open for all "method life".
              ...but this obviously it's no rigth...
              Now i don't know if there is a property to set for leave open the session in a non-web application (i must valorize the DTO only from EJB method and open/close session here) without use OpenSessionInView

              ....someone knows it?

              ..but if you use Declarative Transaction Demarcation and HibernateCallback works...ex:

              getHibernateTemplate().execute(new HibernateCallback() {

              public Object doInHibernate(Session session)
              throws HibernateException, SQLException {

              try {
              A a = (A) session.load(A.class, aId);
              B b = (B) session.load(B.class, bId);
              a.getBs().add(b);
              session.update(a);

              } catch (Exception e) {
              e.printStackTrace();
              return Boolean.FALSE;
              }
              return Boolean.TRUE;

              }

              })

              If there is a property for leave session open or better solution (other code) please tell me...

              Thanks in advance

              Comment

              Working...
              X