2015-04-29 65 views
3

從JSF 1.2升級我的應用程序JSF 2.1後,我已經嘗試下面的Spring Hibernate的異常,當登錄:Spring Hibernate「在託管事務中不能提交!」

DEBUG,[interceptor.ExceptionInterceptor][],org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: commit failed 
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:472) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:392) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    at myapp.aop.interceptor.MethodExceptionInterceptor.invoke(MethodExceptionInterceptor.java:21) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    at myapp.aop.interceptor.SessionActivityInterceptor.invoke(SessionActivityInterceptor.java:47) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) 
    at com.sun.proxy.$Proxy121.endSession(Unknown Source) 
    at myapp.web.action.connection.ConnectionBean.connect(ConnectionBean.java:100) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.jboss.seam.util.Reflections.invoke(Reflections.java:22) 
    at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32) 
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56) 
    at myapp.web.interceptor.ExceptionInterceptor.aroundInvoke(ExceptionInterceptor.java:42) 
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) 
    at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28) 
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) 
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) 
    at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44) 
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) 
    at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:35) 
    at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) 
    at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107) 
    at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:186) 
    at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:104) 
    at myapp.web.action.connection.ConnectionBean_$$_javassist_seam_2.connect(ConnectionBean_$$_javassist_seam_2.java) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335) 
    at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348) 
    at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58) 
    at org.jboss.el.parser.AstValue.invoke(AstValue.java:96) 
    at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276) 
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 
    at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:46) 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101) 
    at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190) 
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:786) 
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1251) 
    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._invokeApplication(LifecycleImpl.java:1074) 
    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:402) 
    at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:225) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) 
    at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:105) 
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502) 
    at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60) 
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:502) 
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:327) 
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:229) 
    at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) 
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) 
    at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60) 
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) 
    at myapp.web.filter.SessionActivityFilter.doFilter(SessionActivityFilter.java:67) 
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) 
    at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40) 
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) 
    at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90) 
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) 
    at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) 
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) 
    at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) 
    at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) 
    at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:389) 
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653) 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920) 
    at java.lang.Thread.run(Thread.java:724) 
Caused by: org.hibernate.TransactionException: commit failed 
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:185) 
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:468) 
    ... 93 more 
Caused by: org.hibernate.TransactionException: unable to commit against JDBC connection 
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:116) 
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:178) 
    ... 94 more 
Caused by: java.sql.SQLException: You cannot commit during a managed transaction! 
    at org.jboss.jca.adapters.jdbc.BaseWrapperManagedConnection.jdbcCommit(BaseWrapperManagedConnection.java:1052) 
    at org.jboss.jca.adapters.jdbc.WrappedConnection.commit(WrappedConnection.java:757) 
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:112) 
    ... 95 more 

這裏是我的Spring bean配置:

<bean id="parentSessionFactory" abstract="true"> 
     <property name="dataSource"> 
      <ref bean="myDS" /> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.connection.driver_class"> 
        org.h2.Driver 
       </prop> 
       <prop key="hibernate.show_sql">false</prop> 
       <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> 
       <prop key="hibernate.cache.use_query_cache">true</prop> 
       <prop key="hibernate.cache.use_second_level_cache">true</prop> 
       <prop key="hibernate.cache.use_structured_cache">true</prop>        
      </props> 
     </property> 
    </bean> 

    <bean id="myDS" 
      class="org.springframework.jndi.JndiObjectFactoryBean"> 
     <property name="jndiName" value="java:/myDS" /> 
    </bean> 


    <bean id="sessionFactory" parent="parentSessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="configLocation"> 
     <value> 
      classpath:model/hibernate.cfg.xml 
     </value> 
     </property> 

     <property name="hibernateProperties"> 
     <props merge="true"> 
      <prop key="hibernate.dialect"> 
       org.hibernate.dialect.H2Dialect 
      </prop>  
     </props>   
     </property> 
    </bean> 

    <bean id="transactionManager" 
     class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory"> 
     <ref bean="sessionFactory"/> 
     </property> 
    </bean> 


    <!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/> bean below) --> 
    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 
    <!-- the transactional semantics... --> 
     <tx:attributes> 
     <!-- all methods starting with 'get' are read-only --> 
     <tx:method name="get*" read-only="true" /> 
     <tx:method name="find*" read-only="true" /> 
     <tx:method name="list*" read-only="true" /> 
     <tx:method name="read*" read-only="true" /> 
     <tx:method name="save*" read-only="false" isolation="READ_COMMITTED"/> 
     <tx:method name="remove*" read-only="false" isolation="READ_COMMITTED"/> 
     <tx:method name="refresh*" read-only="false" isolation="READ_COMMITTED"/> 
     <tx:method name="delete*" read-only="false" isolation="READ_COMMITTED"/> 
     <!-- other methods use the default transaction settings (see below) --> 
     <tx:method name="*" /> 
     </tx:attributes> 
    </tx:advice> 
    <tx:annotation-driven transaction-manager="transactionManager"/> 

<!-- ensure that the above transactional advice runs for any execution 
    of an operation defined by the *Service interface --> 
    <aop:config> 
     <aop:pointcut id="serviceOperation" 
         expression="execution(* services..*Service*.*(..))" /> 
     <aop:pointcut id="daoOperation" 
         expression="execution(* dao..*Dao.*(..))" /> 


     <aop:advisor advice-ref="sessionActivityInterceptor" 
        pointcut-ref="serviceOperation" />   
     <aop:advisor advice-ref="exceptionInterceptor" 
        pointcut-ref="serviceOperation" />  --> 
     <aop:advisor advice-ref="txAdvice" 
        pointcut-ref="serviceOperation" /> 
     <aop:advisor advice-ref="txAdvice" 
        pointcut-ref="daoOperation" />  
    </aop:config> 

這裏是休眠。 cfg.xml中:

<hibernate-configuration> 
    <session-factory> 

     <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property> 
<!--  <property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</property> --> 
     <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> 
     <property name="hibernate.cache.use_query_cache">true</property> 
     <property name="hibernate.cache.use_second_level_cache">true</property> 


     <!-- Several mapping classes here --> 
    </session-factory> 
</hibernate-configuration> 

@Transactional註釋僅在一個方法中使用的我的應用程序和在我的單元測試,但不用於涉及應用程序登錄部分的內容。

調查我的例外進一步我看到,從ironjacamar-jdbc-1.0.17拋出異常BaseWrapperManagedConnection代碼:

/** 
    * JDBC commit 
    * @exception SQLException Thrown if an error occurs 
    */ 
    void jdbcCommit() throws SQLException 
    { 
     synchronized (stateLock) 
     { 
     if (inManagedTransaction) 
      throw new SQLException("You cannot commit during a managed transaction!"); 

     if (jdbcAutoCommit) 
      throw new SQLException("You cannot commit with autocommit set!"); 
     } 
     con.commit(); 

     if (mcf.isJTA().booleanValue()) 
     { 
     if (inLocalTransaction.getAndSet(false)) 
     { 
      Collection<ConnectionEventListener> copy = null; 
      synchronized (cels) 
      { 
       copy = new ArrayList<ConnectionEventListener>(cels); 
      } 

      ConnectionEvent ce = new ConnectionEvent(this, ConnectionEvent.LOCAL_TRANSACTION_COMMITTED); 

      for (Iterator<ConnectionEventListener> i = copy.iterator(); i.hasNext();) 
      { 
       ConnectionEventListener cel = i.next(); 
       try 
       { 
        cel.localTransactionCommitted(ce); 
       } 
       catch (Throwable t) 
       { 
        if (trace) 
        getLog().trace("Error notifying of connection committed for listener: " + cel, t); 
       } 
      } 
     } 
     } 
    } 

變量inManagedTransaction設置爲true在LocalManagedConnection開始方法從ironjacamar-jdbc-1.0.17

/** 
    * {@inheritDoc} 
    */ 
    public void begin() throws ResourceException 
    { 
     lock(); 
     try 
     { 
     synchronized (stateLock) 
     { 
      if (!inManagedTransaction) 
      { 
       try 
       { 
        if (underlyingAutoCommit) 
        { 
        underlyingAutoCommit = false; 
        con.setAutoCommit(false); 
        } 
        checkState(); 
        inManagedTransaction = true; 
       } 
       catch (SQLException e) 
       { 
        checkException(e); 
       } 
      } 
      else 
       throw new ResourceException("Trying to begin a nested local tx"); 
     } 
     } 
     finally 
     { 
     unlock(); 
     } 
    } 

而且inManagedTransaction設置爲false的唯一地方是LocalManagedConnectioncommit()rollback()方法:

/** 
    * {@inheritDoc} 
    */ 
    public void commit() throws ResourceException 
    { 
     lock(); 
     try 
     { 
     synchronized (stateLock) 
     { 
      if (inManagedTransaction) 
       inManagedTransaction = false; 
     } 
     try 
     { 
      con.commit(); 
     } 
     catch (SQLException e) 
     { 
      checkException(e); 
     } 
     } 
     finally 
     { 
     unlock(); 
     } 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public void rollback() throws ResourceException 
    { 
     lock(); 
     try 
     { 
     synchronized (stateLock) 
     { 
      if (inManagedTransaction) 
       inManagedTransaction = false; 
     } 
     try 
     { 
      con.rollback(); 
     } 
     catch (SQLException e) 
     { 
      try 
      { 
       checkException(e); 
      } 
      catch (Exception e2) 
      { 
       // Ignore 
      } 
     } 
     } 
     finally 
     { 
     unlock(); 
     } 
    } 

這是正常的,我有兩個的ManagedConnection一個是BaseWrapperManagedConnection和其他LocalManagedConnection和我經歷他們都犯法的?

我也讀過JBoss也可以處理事務(容器管理的事務)。 Spring和JBoss都試圖處理我的會話和事務嗎?

我正在使用Hibernate 4.2和Spring 3.2.0。 它大部分是經典的配置,就像在網絡上的許多教程中找到什麼都沒有。使用此配置的應用程序正在使用JSF 1.2。 感謝您的任何建議,提示。

+2

從堆棧跟蹤來看,您正在打開和關閉會話,而不是讓Spring爲您處理。我也想知道爲什麼你要混合使用經典的事務配置(xml和point cuts)和'@ Transactional',這會在某些時候咬你。 JSF 1.2和2.x發生了很大的變化升級並不是簡單地替換一個jar,而是需要更多的工作(以我的經驗)。 –

+0

你如何看待我使用@Transactional?其實我沒有使用這個註釋,除了在我的測試中。 – jerome

+0

@ M.Deinum,我如何檢查自己是否打開/關閉會議?但我認爲這不是我的代碼中的情況,但也許jsf 2.1或jboss seam是打開/關閉會話? – jerome

回答

2

您可能在JBoss中配置了一個JTA數據源,它是一個託管事務資源,然後您使用的是非JTA HibernateTransactionManager

爲了解決這個問題,你有兩個選擇:

  1. 你要麼使用RESOURCE_LOCAL數據源並通過JNDI提供它
  2. 你保持JTA數據源,並配置Hibernate與實際Arjuna Transaction Manager
  3. 使用 Spring JtaTransactionManager
+0

就是這樣。 JBoss默認配置爲使用JTA。現在已經修好了,謝謝大家。 – jerome

1

如果您的數據源使用jta,則不得調用transaction.begin既不提交那些由容器調用的事務劃分。 如果您的數據源使用RESOURCE_LOCAL,則必須劃分所有事務,甚至是隻讀的事務。

相關問題