-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Does OSIV work with JTA?
PostPosted: Thu Dec 03, 2009 6:10 pm 
Newbie

Joined: Fri Mar 27, 2009 4:29 pm
Posts: 7
My conclusion has been that it does not, at least not conveniently. Here is why. Sorry for the long post.

Data shown is from an app running with the OSIV servlet filter and a JTA configuration in HBM 3.3.2.GA.

Accessing lazy-loaded child components during JSP rendering produces this exception:

Code:
ERROR [btpool0-1] LazyInitializationException.<init>(19) | could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
   at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
   at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
   at com.e3.model.Form$$EnhancerByCGLIB$$a36161b9.getName(<generated>)
   at ognl.OgnlRuntime.getMethodValue(OgnlRuntime.java:931)
   at ognl.Ognl.getValue(Ognl.java:333)
   at org.apache.jsp.WEB_002dINF.pages.e3core.caseFileForm_jsp._jspx_meth_s_property_18(org.apache.jsp.WEB_002dINF.pages.e3core.caseFileForm_jsp:1670)
   at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:93)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
   at com.e3.webapp.filter.StaticFilter.doFilterInternal(StaticFilter.java:106)
   at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
   at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55)
   at org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:102)
   at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:389)
   at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:406)
   at org.mortbay.jetty.servlet.Dispatcher.forward(Dispatcher.java:285)
   at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:154)
   at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
   at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:361)
   at com.e3.webapp.interceptor.SessionInterceptor.intercept(SessionInterceptor.java:87)
   at com.e3.webapp.interceptor.AuditInterceptor.intercept(AuditInterceptor.java:97)
    ...
   at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
   at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:468)
   at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)
   at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
   at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
   at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)


The SessionFactory is configured this way:
Code:
<bean id="e3SessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
      <property name="dataSource" ref="e3DataSource"/>
      <property name="jtaTransactionManager" ref="jotm"/>
      <property name="annotatedClasses">
          <list>
            <value>com.e3.model.HomeAddress</value>
             <!-- list trimmed for post -->
        </list>
      </property>
      <property name="hibernateProperties">
            <value>
                hibernate.dialect=${hibernate.dialect}
                hibernate.cache.use_second_level_cache=true
                hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
                hibernate.current_session_context_class=jta
                hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory
                hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JOTMTransactionManagerLookup
                hibernate.transaction.auto_close_session=false
                hibernate.connection.release_mode=after_transaction
            </value>
            <!-- jdoc for LocalSessionFactoryBean.setJtaTransactionManager says that if setting that prop,
                  do not set this prop into HBM config
                hibernate.transaction.manager_lookup_class=com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup
             -->
      </property>
      <property name="eventListeners">
          <map>
            <entry key="merge">
                <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
            </entry>
          </map>
      </property>
  </bean>


and JOTM is configured as the JTA transaction manager. Transactions are defined using AOP as:
Code:
<aop:config>
        <aop:advisor id="userManagerTx" advice-ref="userManagerTxAdvice" pointcut="execution(* *..service.UserManager.*(..))" order="0"/>
        <aop:advisor id="userManagerSecurity" advice-ref="userSecurityAdvice" pointcut="execution(* *..service.UserManager.saveUser(..))" order="1"/>
        <aop:advisor id="actionTx" advice-ref="txRequired" pointcut="execution(* *..action.*(..))" order="1" />
        <aop:advisor id="managerTx" advice-ref="txRequired" pointcut="execution(* *..service.*Manager.*(..))" order="2"/>
        <aop:advisor id="daoTx" advice-ref="txSupports" pointcut="execution(* *..dao.*(..))" order="3" />
    </aop:config>

    <tx:advice id="txRequired">
        <tx:attributes>
            <tx:method name="*"  propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <tx:advice id="txSupports">
        <tx:attributes>
            <tx:method name="*" propagation="SUPPORTS" />
        </tx:attributes>
    </tx:advice>

    <tx:advice id="userManagerTxAdvice">
        <tx:attributes>
            <tx:method name="save*" rollback-for="UserExistsException"/>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>


What happens is that the Hibernate property
Code:
                hibernate.current_session_context_class=jta

causes the JTASessionContext class to control creation of HBM sessions. When a session is created, the following logic in JTASessionContext is executed:
Code:
   /**
    * Strictly provided for subclassing purposes; specifically to allow long-session
    * support.
    * <p/>
    * This implementation always just opens a new session.
    *
    * @return the built or (re)obtained session.
    */
   protected Session buildOrObtainSession() {
      return factory.openSession(
            null,
              isAutoFlushEnabled(),
              isAutoCloseEnabled(),
              getConnectionReleaseMode()
         );
   }

   /**
    * Mainly for subclass usage.  This impl always returns true.
    *
    * @return Whether or not the the session should be closed by transaction completion.
    */
   protected boolean isAutoCloseEnabled() {
      return true;
   }


This is an example of its execution:
Code:
*** AutoCloseSession enabled on Session construction ***
java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Unknown Source)
        at org.hibernate.impl.SessionImpl.<init>(SessionImpl.java:243)
        at org.hibernate.impl.SessionFactoryImpl.openSession(SessionFactoryImpl.java:605)
        at org.hibernate.context.JTASessionContext.buildOrObtainSession(JTASessionContext.java:152)
        at org.hibernate.context.JTASessionContext.currentSession(JTASessionContext.java:111)
        at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
        at com.e3.dao.hibernate.GenericDaoHibernate.getHbmSession(GenericDaoHibernate.java:523)
        at com.e3.dao.hibernate.GenericDaoHibernate.find(GenericDaoHibernate.java:109)
        at com.e3.service.impl.GenericManagerImpl.find(GenericManagerImpl.java:130)
        at com.e3.service.impl.GenericManagerImpl$$FastClassByCGLIB$$e6c38d98.invoke(<generated>)
        at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
        at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:70
0)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
        at com.e3.service.impl.GenericManagerImpl$$EnhancerByCGLIB$$1551eeb5.find(<generated>)
        at com.e3.webapp.action.CaseFileAction.list(CaseFileAction.java:178)


and after the business methods executes, the org.hibernate.transaction.CacheSynchronization class uses the auto-close property to terminate the current session
Code:
   /**
    * {@inheritDoc}
    */
   public void afterCompletion(int status) {
      if ( log.isTraceEnabled() ) {
         log.trace("transaction after completion callback, status: " + status);
      }
      try {
         jdbcContext.afterTransactionCompletion(status==Status.STATUS_COMMITTED, hibernateTransaction);
      }
      finally {
         if ( ctx.shouldAutoClose() && !ctx.isClosed() ) {
            log.trace("automatically closing session");
            ctx.managedClose();
         }
      }
   }


that we can see here
Code:
       at java.lang.Thread.dumpStack(Unknown Source)
        at org.hibernate.impl.SessionImpl.managedClose(SessionImpl.java:383)
        at org.hibernate.transaction.CacheSynchronization.afterCompletion(CacheSynchronization.java:122)
        at org.objectweb.jotm.SubCoordinator.doAfterCompletion(SubCoordinator.java:1569)
        at org.objectweb.jotm.SubCoordinator.doOnePhaseCommit(SubCoordinator.java:1278)
        at org.objectweb.jotm.SubCoordinator.commit_one_phase(SubCoordinator.java:451)
        at org.objectweb.jotm.TransactionImpl.commit(TransactionImpl.java:239)
        at org.objectweb.jotm.Current.commit(Current.java:488)
        at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1028)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTran
sactionManager.java:732)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransaction
Manager.java:701)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(Transact
ionAspectSupport.java:321)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
        at com.e3.service.impl.GenericManagerImpl$$EnhancerByCGLIB$$40735a67.find(<generated>)
        at com.e3.webapp.action.CaseFileAction.list(CaseFileAction.java:178)


I found that modifying JTASessionContext to return 'false' from isAutoCloseEnabled() keeps the HBM session open beyond the normal end of the transaction, thereby allowing the view to render. The filter then closes the session.

However, to my fairly newbie understanding, a 'proper' solution to this problem is really to include the view in the transaction -- by pre-compiling the JSPs and include their class definitions in the AOP declaration.

Can anyone report they they successfully use JTA with an OSIV filter? Does this require JSP precompilation, or am I missing something?

Thanks for ideas -


Top
 Profile  
 
 Post subject: Re: Does OSIV work with JTA?
PostPosted: Wed Jun 30, 2010 9:28 am 
Newbie

Joined: Wed Dec 06, 2006 6:50 pm
Posts: 7
Hi, I´m experiencing exactly the same problem. The only difference is that I´m using JTA embedded in JBOSS Server. Have you solved your problem? Everything is always perfect and functional in the books, but the true is much more complicated when we put our hands on code. This is really frustating.

Thank´s


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.