Java 单元测试代码,使用JPA&;JTA

Java 单元测试代码,使用JPA&;JTA,java,unit-testing,jpa,ejb-3.0,jta,Java,Unit Testing,Jpa,Ejb 3.0,Jta,我使用两个独立的数据库,所以我必须使用JTA来处理分布式事务。所以要么两个数据库都必须提交,要么两个回滚。我使用OpenJPA和JTA。现在使用junit对代码进行单元测试?当我试图运行处理分布式事务的代码时,我遇到了以下错误。我在这个网站上发布了类似的问题,有人让我参考 但是从那里我什么都听不懂 <openjpa-1.2.1-SNAPSHOT-r422266:686069 fatal store error> org.apache.openjpa.persistence.Rollb

我使用两个独立的数据库,所以我必须使用JTA来处理分布式事务。所以要么两个数据库都必须提交,要么两个回滚。我使用OpenJPA和JTA。现在使用junit对代码进行单元测试?当我试图运行处理分布式事务的代码时,我遇到了以下错误。我在这个网站上发布了类似的问题,有人让我参考 但是从那里我什么都听不懂

<openjpa-1.2.1-SNAPSHOT-r422266:686069 fatal store error> org.apache.openjpa.persistence.RollbackException: Unable to obtain a TransactionManager using null. 
    at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:523)
    at com.XYZ.cloud.admin.loadCatalog.LoadCatalogTest.populateOffering(LoadCatalogTest.java:253)
    at com.XYZ.cloud.admin.loadCatalog.LoadCatalogTest.CatalogUploadTest(LoadCatalogTest.java:160)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:599)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
    at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: <openjpa-1.2.1-SNAPSHOT-r422266:686069 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: Unable to obtain a TransactionManager using null. 
    at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4231)
    at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4196)
    at org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:503)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:102)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:88)
    at org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:64)
    at org.apache.openjpa.jdbc.kernel.AbstractJDBCSeq.next(AbstractJDBCSeq.java:65)
    at org.apache.openjpa.util.ImplHelper.generateValue(ImplHelper.java:160)
    at org.apache.openjpa.util.ImplHelper.generateFieldValue(ImplHelper.java:144)
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.assignField(JDBCStoreManager.java:698)
    at org.apache.openjpa.util.ApplicationIds.assign(ApplicationIds.java:487)
    at org.apache.openjpa.util.ApplicationIds.assign(ApplicationIds.java:463)
    at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.assignObjectId(JDBCStoreManager.java:682)
    at org.apache.openjpa.kernel.DelegatingStoreManager.assignObjectId(DelegatingStoreManager.java:134)
    at org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:519)
    at org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:2823)
    at org.apache.openjpa.kernel.PNewState.beforeFlush(PNewState.java:39)
    at org.apache.openjpa.kernel.StateManagerImpl.beforeFlush(StateManagerImpl.java:959)
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1948)
    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1908)
    at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1826)
    at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
    at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1350)
    at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:877)
    at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:512)
    ... 26 more
Caused by: java.sql.SQLException: Unable to obtain a TransactionManager using null. 
    at org.apache.openjpa.jdbc.kernel.TableJDBCSeq.allocateSequence(TableJDBCSeq.java:419)
    at org.apache.openjpa.jdbc.kernel.TableJDBCSeq.nextInternal(TableJDBCSeq.java:290)
    at org.apache.openjpa.jdbc.kernel.AbstractJDBCSeq.next(AbstractJDBCSeq.java:60)
    ... 44 more
Caused by: javax.transaction.NotSupportedException: Unable to obtain a TransactionManager using null. 
    at org.apache.openjpa.ee.AutomaticManagedRuntime.doNonTransactionalWork(AutomaticManagedRuntime.java:306)
    at org.apache.openjpa.jdbc.kernel.TableJDBCSeq.allocateSequence(TableJDBCSeq.java:415)
    ... 46 more
Caused by: <openjpa-1.2.1-SNAPSHOT-r422266:686069 fatal user error> org.apache.openjpa.util.InvalidStateException: Could not perform automatic lookup of EJB container's javax.transaction.TransactionManager implementation. Please ensure that you are running the application from within an EJB 1.1 compliant EJB container, and then set the org.apache.openjpa.ManagedRuntime property to  
    at org.apache.openjpa.ee.AutomaticManagedRuntime.getTransactionManager(AutomaticManagedRuntime.java:250)
    at org.apache.openjpa.ee.AutomaticManagedRuntime.doNonTransactionalWork(AutomaticManagedRuntime.java:304)
    ... 47 more
Caused by: javax.naming.ConfigurationException: Name space accessor for the java: name space has not been set. Possible cause is that the user is specifying a java: URL name in a JNDI Context method call but is not running in a J2EE client or server environment.
    at com.XYZ.ws.naming.java.javaURLContextFactory.isNameSpaceAccessable(javaURLContextFactory.java:93)
    at com.XYZ.ws.naming.urlbase.UrlContextFactory.getObjectInstance(UrlContextFactory.java:82)
    at javax.naming.spi.NamingManager.getURLContext(NamingManager.java:655)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:434)
    at javax.naming.InitialContext.lookup(InitialContext.java:450)
    at org.apache.openjpa.ee.RegistryManagedRuntime.getTransactionManager(RegistryManagedRuntime.java:61)
    at org.apache.openjpa.ee.AutomaticManagedRuntime.getTransactionManager(AutomaticManagedRuntime.java:154)
    ... 48 more
org.apache.openjpa.persistence.RollbackException:无法使用null获取TransactionManager。
位于org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:523)
位于com.XYZ.cloud.admin.loadCatalog.LoadCatalogTest.populateOffering(LoadCatalogTest.java:253)
位于com.XYZ.cloud.admin.loadCatalog.LoadCatalogTest.CatalogPloadTest(LoadCatalogTest.java:160)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)中
位于java.lang.reflect.Method.invoke(Method.java:599)
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:44)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:41)
位于org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
位于org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
位于org.junit.internal.runners.statements.runafter.evaluate(runafter.java:31)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
位于org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
位于org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
位于org.junit.internal.runners.statements.runafter.evaluate(runafter.java:31)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:220)
位于org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
位于org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
原因:org.apache.openjpa.persistence.PersistenceException:无法使用null获取TransactionManager。
位于org.apache.openjpa.jdbc.sql.DBDictionary.窄(DBDictionary.java:4231)
位于org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4196)
位于org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:503)
位于org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:102)
位于org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:88)
位于org.apache.openjpa.jdbc.sql.SQLExceptions.getStore(SQLExceptions.java:64)
位于org.apache.openjpa.jdbc.kernel.AbstractJDBCSeq.next(AbstractJDBCSeq.java:65)
位于org.apache.openjpa.util.ImplHelper.generateValue(ImplHelper.java:160)
位于org.apache.openjpa.util.ImplHelper.generateFieldValue(ImplHelper.java:144)
位于org.apache.openjpa.jdbc.kernel.JDBCStoreManager.assignField(JDBCStoreManager.java:698)
位于org.apache.openjpa.util.ApplicationIds.assign(ApplicationIds.java:487)
位于org.apache.openjpa.util.ApplicationIds.assign(ApplicationIds.java:463)
位于org.apache.openjpa.jdbc.kernel.JDBCStoreManager.assignObjectId(JDBCStoreManager.java:682)
位于org.apache.openjpa.kernel.DelegatingStoreManager.assignObjectId(DelegatingStoreManager.java:134)
位于org.apache.openjpa.kernel.StateManagerImpl.assignObjectId(StateManagerImpl.java:519)
位于org.apache.openjpa.kernel.StateManagerImpl.preFlush(StateManagerImpl.java:2823)
位于org.apache.openjpa.kernel.PNewState.beforeFlush(PNewState.java:39)
位于org.apache.openjpa.kernel.StateManagerImpl.beforeFlush(StateManagerImpl.java:959)
位于org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1948)
位于org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1908)
在org.apache.openjpa.kernel.BrokerImpl.beforepletion上(BrokerImpl.java:1826)
位于org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
位于org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1350)
位于org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:877)
位于org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:512)
... 26多
原因:java.sql.SQLException:无法使用null获取TransactionManager。
位于org.apache.openjpa.jdbc.kernel.TableJDBCSeq.allocateSequence(TableJDBCSeq.java:419)
位于org.apache.openjpa.jdbc.kernel.TableJDBCSeq.nextInternal(TableJDBCSeq.java:290)
在org.apache.openjpa.jdbc.kernel.AbstractJDBCSeq.next(AbstractJDBCSeq.java:60)
... 44多
原因:javax.transaction.NotSupportedException:无法使用null获取TransactionManager。
位于org.apache.openjpa.ee.AutomaticManagedRuntime.donOnTransactionWork(AutomaticManagedRuntime.java:306)
位于org.apache.openjpa.jdbc.kernel.TableJDBCSeq.allocateSequence(TableJDBCSeq.java:415)
... 46多
原因:org.apache.openjpa.util.InvalidStateException:无法自动查找EJB容器的javax.transaction.TransactionManager实现。请确保
<dependency>
    <!-- It's provided by Glassfish but while testing OpenEJB needs it explicitly -->
    <groupId>toplink.essentials</groupId>
    <artifactId>toplink-essentials</artifactId>
    <version>2.0-58g</version>
</dependency>

<dependency>
    <!-- not sure about this one but probably it's needed -->
    <groupId>org.glassfish</groupId>
    <artifactId>javax.servlet</artifactId>
    <version>3.0</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.apache.openejb</groupId>
    <artifactId>openejb-core</artifactId>
    <version>3.0.2</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.13</version>
    <scope>test</scope>
</dependency>
public abstract class AbstractOpenEjbTest {

    private static final String JTA_DATA_SOURCE = "jdbc/SeobserwatorDS";

    protected static InitialContext context;

    @BeforeClass
    public static void createInitialContext() throws Exception {
        setSystemProperties();

        final Properties properties = new Properties();

        properties.setProperty(JTA_DATA_SOURCE, "new://Resource?type=DataSource");
        properties.setProperty(JTA_DATA_SOURCE + ".JdbcDriver", "com.mysql.jdbc.Driver");
        properties.setProperty(JTA_DATA_SOURCE + ".JdbcUrl", "jdbc:mysql://localhost:3306/inne_test");
        properties.setProperty(JTA_DATA_SOURCE + ".UserName", "xxx");
        properties.setProperty(JTA_DATA_SOURCE + ".Password", "yyy");

        context = new InitialContext(properties);
    }

    @BeforeClass
    public static void setSystemProperties() {
        System.setProperty("java.naming.factory.initial", "org.apache.openejb.client.LocalInitialContextFactory");
        System.setProperty("toplink.target-server", "net.nowaker.nhr.seobserwator.web.OpenEjbTransactionController");
        System.setProperty("toplink.ddl-generation", "drop-and-create-tables");
        System.setProperty("toplink.logging.level", "WARNING");
        System.setProperty("toplink.ddl-generation.output-mode", "both");
    }

    @SuppressWarnings("unchecked")
    public AbstractOpenEjbTest() {
        // Execute manually all ServletContextListeners as we are outside the container
    }

    @AfterClass
    public static void removeTables() throws Exception {
        // some clean-up, e.g. delete all data
    }
}
import javax.transaction.TransactionManager;
import oracle.toplink.essentials.transaction.JTATransactionController;

/**
 * Transaction controller for OpenEJB standalone/embedded and Toplink
 *
 * @see http://qbeukes.blogspot.com/2008/08/toplink-as-your-openejb-persistence.html
 */
public class OpenEjbTransactionController extends JTATransactionController {

    public static final String JNDI_TRANSACTION_MANAGER_NAME = "java:comp/TransactionManager";

    public OpenEjbTransactionController() {
        super();
    }

    @Override
    protected TransactionManager acquireTransactionManager() throws Exception {
        return (TransactionManager) jndiLookup(JNDI_TRANSACTION_MANAGER_NAME);
    }
}
public class OpenEjbTest extends AbstractOpenEjbTest {

    @Test
    public void shouldAddUserWithStatelessBean() throws Exception {
        // when
        final AuthServiceLocal authService = EjbUtils.lookupBean(AuthServiceLocal.class);
        final CrudServiceLocal crudService = EjbUtils.lookupBean(CrudServiceLocal.class);

        // then
        assertFalse(authService.userExists("nonExistent"));
        final User unmanagedUser = new User(null, "a", "b", "c", "d", 12345678, new Date());
        final User managedUser = crudService.update(unmanagedUser);
        assertNotNull(managedUser.getId());
        assertNotNull(crudService.find(User.class, managedUser.getId()));
    }
}