如何在 POJO 中获取 EntityManager?

How to get a EntityManager in a POJO?

我目前正在重构旧的遗留代码并用 EJB 3.0 / 3.1 替换或删除所有 EJB 2.0 引用。我遇到了一个实用程序 class,它提供我们 Oracle 数据库 (11g / 12c) 的当前日期 (java.util.Date) 或时间戳 (java.sql.Timestamp)。对数据库的访问是通过 java.sql.Connection 实现的,该 java.sql.Connection 是通过查找 javax.naming.InitialContext.

获得的

我想通过 JPA 或 Hibernate 解决这个问题并使用新的 Java Date/Time API。所以我重写了实用程序 class,但我无法获得有效的 javax.persistence.EntityManager 实例。

实用程序 class 与其他现有的无状态会话和实体 bean 一起打包在一个包含在耳朵内的 server.jar 中。持久性单元 "seller-em" 已经存在并被会话和实体 bean 使用。当我尝试调用函数 getEm() 时,我在执行 emf.createEntitymanager 时得到 java.lang.NullPointerException

我还尝试让 Wildfly(8.2.1 Final)注入实体管理器:

@PersistenceContext(unitName = "seller-em")
private EntityManager em;

但是 em 为空。

我已经花了一天时间在 google 和这里寻找提示。任何我出错的想法或者任何人都可以给我一个正确方向的提示吗?

此致,
CB

环境:
Java8 (1.8.0_77)
Eclipse Mars R2 (4.5.2)
Maven 3.3.3
(JBoss) Wildfly 8.2.1 Final

附件:

package org.example.server.seller.tools;

import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class DateUtility {
    private static final String ORACLE_ISO_8601_FORMAT_STRING = "YYYY-MM-DD\"T\"HH:MI:SS.FF6TZH:TZM";
    // 12/31/2999 00:00:00.000000 +01:00 (ECT / European Central Time / TZ:Europe/Berlin)
    // Using Z time, because +01:00, ECT, ECT, UTC+1, etc. results in a java.time.format.DateTimeParseException.
    private static final Instant MAXIMUM_DATE_TIME = Instant.parse("2999-12-30T23:00:00.000000Z");
    private static final Object TREE_LOCK = new Object();

    private static EntityManager getEm() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("seller-em");
        return emf.createEntityManager();
    }

    public static Instant getDatabaseSystemTimestamp() {
        // EntityManager is not thread-safe, we need to synchronie it.
        synchronized (TREE_LOCK) {
            Query query = getEm().createNativeQuery("SELECT TO_CHAR( SYSTIMESTAMP, :formatString) FROM DUAL");
            query.setParameter("formatString", ORACLE_ISO_8601_FORMAT_STRING);
            String iso8601String = (String) query.getSingleResult();
            return Instant.parse(iso8601String);
        }
    }

    public static Instant getMaximumDateTime() {
        return MAXIMUM_DATE_TIME;
    }

    public static LocalDateTime getCurrentDateTime() {
        return LocalDateTime.ofInstant(getDatabaseSystemTimestamp(), ZoneId.of("Europe/Berlin"));
    }

    public static LocalDate getCurrentDate() {
        return getCurrentDateTime().toLocalDate();
    }

    public static LocalTime getCurrentTime() {
        return getCurrentDateTime().toLocalTime();
    }

    /*
     * Just for backwards compatibility. Opted for java.sql.Timestamp since it is an extension of java.util.Date and
     * therefore can also be used a Date.
     */
    @Deprecated
    public static Timestamp getCurrentDateTimeAsTimestamp() {
        return Timestamp.from(getDatabaseSystemTimestamp());
    }
}

和堆栈跟踪:

java.lang.NullPointerException
    at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:76)
    at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:118)
    at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1602)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:210)
    at org.hibernate.jpa.internal.EntityManagerImpl.<init>(EntityManagerImpl.java:91)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.internalCreateEntityManager(EntityManagerFactoryImpl.java:345)
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313)
    at org.example.server.seller.tools.DateUtility.getEm(DateUtility.java:26)
    at org.example.server.seller.tools.DateUtility.getDatabaseSystemTimestamp(DateUtility.java:32)
    at org.example.server.seller.tools.DateUtilityTest.testDateUtility(DateUtilityTest.java:94)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.jboss.arquillian.junit.Arquillian.invoke(Arquillian.java:270)
    at org.jboss.arquillian.container.test.impl.execution.LocalTestExecuter.execute(LocalTestExecuter.java:60)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)
    at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:135)
    at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:115)
    at org.jboss.arquillian.core.impl.EventImpl.fire(EventImpl.java:67)
    at org.jboss.arquillian.container.test.impl.execution.ContainerTestExecuter.execute(ContainerTestExecuter.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)
    at org.jboss.arquillian.test.impl.TestContextHandler.createTestContext(TestContextHandler.java:102)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.test.impl.TestContextHandler.createClassContext(TestContextHandler.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.test.impl.TestContextHandler.createSuiteContext(TestContextHandler.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
    at org.jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
    at org.jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:135)
    at org.jboss.arquillian.test.impl.EventTestRunnerAdaptor.test(EventTestRunnerAdaptor.java:111)
    at org.jboss.arquillian.junit.Arquillian.evaluate(Arquillian.java:263)
    at org.jboss.arquillian.junit.Arquillian.evaluate(Arquillian.java:226)
    at org.jboss.arquillian.junit.Arquillian.multiExecute(Arquillian.java:314)
    at org.jboss.arquillian.junit.Arquillian.access0(Arquillian.java:46)
    at org.jboss.arquillian.junit.Arquillian.evaluate(Arquillian.java:240)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:53)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)
    at org.jboss.arquillian.junit.Arquillian.evaluate(Arquillian.java:185)
    at org.jboss.arquillian.junit.Arquillian.multiExecute(Arquillian.java:314)
    at org.jboss.arquillian.junit.Arquillian.access0(Arquillian.java:46)
    at org.jboss.arquillian.junit.Arquillian.evaluate(Arquillian.java:199)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.jboss.arquillian.junit.Arquillian.run(Arquillian.java:147)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
    at org.jboss.arquillian.junit.container.JUnitTestRunner.execute(JUnitTestRunner.java:65)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.executeTest(ServletTestRunner.java:160)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.execute(ServletTestRunner.java:126)
    at org.jboss.arquillian.protocol.servlet.runner.ServletTestRunner.doGet(ServletTestRunner.java:90)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70)
    at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:248)
    at io.undertow.servlet.handlers.ServletInitialHandler.access[=12=]0(ServletInitialHandler.java:77)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:167)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199)
    at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:761)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">

    <persistence-unit name="seller-em">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/DBUNIT</jta-data-source>
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
        </properties>
    </persistence-unit>

</persistence>

我自己找到了解决办法。发布堆栈跟踪后,我在 class JtaStatusHelper 上查找了 NPE,并在 Whosebug 上找到了一个命中。在 this thread 我找到了决定性的提示。

我将以下行添加到我的 persistence.xml 并且它有效:

<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />

感谢您的帮助。
最好的再努力,
CB