2015-01-08 50 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