【问题标题】:Issues while running JUnit on maven project using Spring JTA使用 Spring JTA 在 maven 项目上运行 JUnit 时出现问题
【发布时间】:2014-09-21 15:57:32
【问题描述】:

我在 JBoss 5 上部署了一个 Spring + Hibernate 项目。它之前使用的是 Ant,最近我修改了项目结构以使用 Maven 2。但是所有的代码和配置文件都是一样的。

我在我的项目中使用 Spring JTA 进行事务管理。我能够完美地构建项目并将其部署在 JBoss 上。但是当我尝试执行 JUnit 测试时,它给了我以下错误:

java.lang.IllegalStateException: No JTA UserTransaction available - specify either 'userTransaction' or 'userTransactionName' or 'transactionManager' or 'transactionManagerName'
    at org.springframework.transaction.jta.JtaTransactionManager.checkUserTransactionAndTransactionManager(JtaTransactionManager.java:473)
    at org.springframework.transaction.jta.JtaTransactionManager.afterPropertiesSet(JtaTransactionManager.java:413)

奇怪的是,当我使用 Ant 时,它工作得非常好。它在迁移到 maven 后开始出现。

这是 spring-jpa-conf.xml 文件中的条目:

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
</bean>

这是 Junit 代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring-conf.xml" })
@Transactional(value = "transactionManager")
public abstract class LocalUsersTestBase {

    @PersistenceContext(unitName="books-lemf")
    protected EntityManager entityManager;

    protected void getUsersDetails(List<Users> out) {
            ..........
}

我还尝试在配置文件条目中添加一个属性,如下所示:

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

但它给出了错误:

Caused by: org.springframework.transaction.TransactionSystemException: JTA UserTransaction is not available at JNDI location [java:/TransactionManager]; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at org.springframework.transaction.jta.JtaTransactionManager.lookupUserTransaction(JtaTransactionManager.java:548)
    at org.springframework.transaction.jta.JtaTransactionManager.initUserTransactionAndTransactionManager(JtaTransactionManager.java:425)
    at org.springframework.transaction.jta.JtaTransactionManager.afterPropertiesSet(JtaTransactionManager.java:412)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1460)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1400)
    ... 37 more
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)

请帮忙。

谢谢!!

这是我完整的 spring 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
        </bean>

    <jee:jndi-lookup id="books-pu" 
        jndi-name="java:/books-emf" 
        cache="true"
        lookup-on-startup="false"
        proxy-interface="javax.persistence.EntityManagerFactory"
    />

    <jee:jndi-lookup id="booksDataSource" jndi-name="java:/books-ds"/>


</beans>

【问题讨论】:

    标签: spring maven junit jta


    【解决方案1】:

    首先,来自 spring 参考文档

    如果您在 Java EE 容器中使用 JTA,那么您使用的是容器 数据源 , 通过 JNDI 获得, 结合 Spring 的 JtaTransactionManager .这就是 JTA 和 JNDI 查找版本 看起来像:

    JtaTransactionManager 不需要知道 数据源 ,或任何其他特定的 资源,因为它使用容器的全局事务管理基础架构

    然后,当您运行测试时,您需要一个环境容器来管理以获取 JTA 用户事务。另外可以和我们分享一下完整的spring配置吗

    【讨论】:

    • 感谢您的回复。是的,我在我的配置文件中使用了数据源。
    • 我已经粘贴了我的配置文件的全部内容。
    • 我认为属性 jndi-name 已绑定到您的应用程序服务器。在测试阶段,您没有管理环境容器,并且您遇到了上述异常。尝试使用 arquillan 进行此类测试
    猜你喜欢
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 2016-02-16
    • 2014-06-15
    • 1970-01-01
    • 2011-10-09
    • 2014-06-02
    • 1970-01-01
    相关资源
    最近更新 更多