2015-01-08 125 views
0

首先,我不能使用Spring的@Transactional註釋。我必須使用完全在EJB容器中的JTA。我正在使用JBoss AS 7.0 Web-Profile。所以我需要做的就是配置Hibernate的會話工廠,以便在Spring的Envirnoment中正確使用JTA -transaction。我目前的配置:我的配置spring sessionFactory配置有什麼問題?

一塊context.xml配置:

<tx:annotation-driven/> 
<tx:jta-transaction-manager /> 

<!-- Some other beans --> 

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

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="annotatedClasses"> 
     <list> 
      <value>com.badmitrii.db.entity.Employee</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> 
      <prop key="hibernate.show_sql">false</prop> 
     </props>    
    </property> 
</bean> 

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 
    <property name="userTransaction" ref="userTransaction"></property> 
</bean> 

DAO-方法:

public Player getPlayerById(Integer id){ 
    try { 
     userTransaction.begin(); 
    } catch (Exception e) { } 

    //Here is obtaining a Criteria object and setting Restrictions 

    try { 
     userTransaction.commit(); 
    } catch (Exception e) { } 
    return (Player) criteria.uniqueResult(); 
} 

但是,我當我試圖在DAO方法來獲取會話以下錯誤時拋出:

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread 
    org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134) 
    org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1024) 
    com.badmitrii.db.dao.EmployeeDAOImpl.getEmployeeById(EmployeeDAOImpl.java:34) 
    com.badmitrii.EmployeeListController.getEmployeeById(EmployeeListController.java:42) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    java.lang.reflect.Method.invoke(Method.java:483) 
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) 
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777) 
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706) 
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) 
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) 
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:734) 
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
    javax.servlet.http.HttpServlet.service(HttpServlet.java:847) 

如何正確配置它?

+2

沒有理由不能在JTA環境中使用'@ Transactional'。 「@ Transactional」或聲明式事務管理的重點在於它是否適用於本地或分佈式事務。 –

+0

@ M.Deinum如果我開始使用spring的事務,我將不得不刪除項目其餘部分中的所有JTA事務。 – user3663882

+0

不,你似乎對此事缺乏瞭解。 –

回答

1

首先刪除JtaTransactionManager的聲明,這已經由<tx:jta-transaction-manager />提供。

接下來,沒有理由不能在JTA環境中使用@Transactional,這是整個聲明性tx管理的要點。

您應該將配置的jta事務管理器連線到LocalSessionFactoryBean以將使用的CurrentSessionContext切換出去。

<tx:annotation-driven/> 
<tx:jta-transaction-manager /> 

<!-- Some other beans --> 

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

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="jtaTransactionManager" ref="transactionManager" /> 
    <property name="annotatedClasses"> 
     <list> 
      <value>com.badmitrii.db.entity.Employee</value> 
     </list> 
    </property> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> 
      <prop key="hibernate.show_sql">false</prop> 
     </props>    
    </property> 
</bean> 

然後在你的鱈魚億郵可以簡單地做這樣的事情

@Transactional 
public Player getPlayerById(Integer id){ 
    //Here is obtaining a Criteria object and setting Restrictions 
    return (Player) criteria.uniqueResult(); 
} 

更新:

對於JBoss的<tx:jta-transaction-manager />不起作用由於事實TransactionManager的JTA是在JNDI中以名稱java:jboss/TransactionManager註冊,而不是well-known names之一。您需要自行聲明JtaTransactionManager bean並刪除<tx:jta-transaction-manager />元素。對於查找,您需要指定transactionManagerName或自己執行JNDI查找。

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> 
    <property name="transactionManagerName" value="java:jboss/TransactionManager" /> 
</bean> 

UserTransaction下的默認名稱註冊的,因此您可以忽略它注射在JtaTransactionManager,因爲它會做的查找自身。

+0

太棒了,你節省了我的時間,謝謝。不行。但是我會提供一些關於配置的註釋。 – user3663882

+0

我剛剛嘗試過你寫的內容,但沒有起作用。當我們聲明'org.springframework.transaction.jta.JtaTransactionManager'時,我們將不得不顯式地提供bean的transactionManager屬性,否則就會拋出異常。在我的例子中,它是JbossTransactionManager,它可以通過它的jndi-name'java:jboss/TransactionManager'找到。 – user3663882

+0

此外,正如所說的http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html,''註釋將要適用於唯一的WebLogic Server和WebSphere。 – user3663882