当前位置: 首页 > 知识库问答 >
问题:

在大多数基本示例中,无法使用@PersistenceContext注入EntityManager

容俊豪
2023-03-14

为了使用实体管理器的PersistenceContext注入来测试JPA,我有一个基本的示例项目,其结构如下:Person entity:

@Entity
public class Person {

    @Id
    @GeneratedValue
    private long id;
    private String name;
    private String surname;

    public Person() {
    }

    public Person(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (id != person.id) return false;
        if (name != null ? !name.equals(person.name) : person.name != null) return false;
        return surname != null ? surname.equals(person.surname) : person.surname == null;
    }

    @Override
    public int hashCode() {
        int result = (int) (id ^ (id >>> 32));
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (surname != null ? surname.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", surname='" + surname + '\'' +
                '}';
    }
}

Rest配置:

@ApplicationPath("/api")
public class RestConfig extends Application {
}

测试restendpoint:

@Path("/test")
//@Vetoed
public class TestResource {

    @PersistenceContext(unitName = "pu")
    private EntityManager entityManager;

    @GET
    @Path("/dbtest")
    public Response testDb() {
        System.out.println("DBG Invocation of dbtest");
        Person person=new Person("tomas","bisciak");
        entityManager.persist(person); //ALWAYS NULL
        System.out.println("Persisted");
        Person retrievedEntity= entityManager.find(Person.class,1);
        System.out.println("Retrieved entity:"+retrievedEntity);
        return Response.status(Response.Status.OK).build();
    }

}

persistence.xml

<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="pu" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>java:jboss/datasources/MySqlDS2</jta-data-source>

        <class>Person</class>

        <properties>

            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/xchange" />

            <property name="eclipselink.logging.level" value="FINE"/>
            <property name="eclipselink.target-database" value="MySQL"/>
            <property name="eclipselink.ddl-generation" value="create-tables" />
        </properties>
    </persistence-unit>
</persistence>

在我的wildfly Standalone.xml中定义的数据源:

 <datasource jndi-name="java:jboss/datasources/MySqlDS2" pool-name="MySqlDS2" enabled="true" use-java-context="true">
                    <connection-url>jdbc:mysql://localhost:3306/xchange</connection-url>
                    <driver-class>com.mysql.jdbc.Driver</driver-class>
                    <driver>mysql-connector-java-5.1.45-bin.jar_com.mysql.jdbc.Driver_5_1</driver>
                    <security>
                        <user-name>root</user-name>
                        <password>root</password>
                    </security>
                </datasource>

具有war结构的项目结构:

并在我的pom.xml中执行以下操作:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bisciak.jpa</groupId>
    <artifactId>jpatest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <java.version>1.8</java.version>

        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>

        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>


    <dependencies>

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>



        <!-- https://mvnrepository.com/artifact/org.eclipse.persistence/eclipselink -->
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.7.1</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>

        <!--Testing dependencies-->

        <!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.13.0</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>


</project>

所有这些都运行在最新的稳定的Wildfly上,我得到的输出是:

Connected to server
[2018-01-29 03:17:37,085] Artifact jpatest:war exploded: Artifact is being deployed, please wait...
15:17:37,168 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-2) WFLYSRV0027: Starting deployment of "jpatest-1.0-SNAPSHOT" (runtime-name: "jpatest-1.0-SNAPSHOT.war")
15:17:38,312 INFO  [org.jboss.weld.deployer] (MSC service thread 1-5) WFLYWELD0003: Processing weld deployment jpatest-1.0-SNAPSHOT.war
15:17:38,351 INFO  [org.hibernate.validator.internal.util.Version] (MSC service thread 1-5) HV000001: Hibernate Validator 5.3.5.Final
15:17:38,516 INFO  [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-5) WFLYJCA0005: Deploying non-JDBC-compliant driver class com.mysql.cj.jdbc.Driver (version 6.0)
15:17:38,537 INFO  [org.jboss.weld.Version] (MSC service thread 1-5) WELD-000900: 2.4.3 (Final)
15:17:38,574 INFO  [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-1) WFLYJCA0018: Started Driver service with driver-name = jpatest-1.0-SNAPSHOT.war_com.mysql.cj.jdbc.Driver_6_0
15:17:38,896 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-6) MSC000001: Failed to start service jboss.deployment.unit."jpatest-1.0-SNAPSHOT.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."jpatest-1.0-SNAPSHOT.war".WeldStartService: Failed to start service
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1978)
    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)
Caused by: java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named 'pu' in deployment jpatest-1.0-SNAPSHOT.war for injection point private javax.persistence.EntityManager TestResource.entityManager
    at org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.getScopedPUName(WeldJpaInjectionServices.java:114)
    at org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.registerPersistenceContextInjectionPoint(WeldJpaInjectionServices.java:77)
    at org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:350)
    at org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:338)
    at org.jboss.weld.injection.ResourceInjectionFactory$ResourceInjectionProcessor.createFieldResourceInjection(ResourceInjectionFactory.java:216)
    at org.jboss.weld.injection.ResourceInjectionFactory$ResourceInjectionProcessor.createResourceInjections(ResourceInjectionFactory.java:188)
    at org.jboss.weld.injection.ResourceInjectionFactory.discoverType(ResourceInjectionFactory.java:448)
    at org.jboss.weld.injection.ResourceInjectionFactory.getResourceInjections(ResourceInjectionFactory.java:96)
    at org.jboss.weld.injection.producer.ResourceInjector.<init>(ResourceInjector.java:59)
    at org.jboss.weld.injection.producer.ResourceInjector.of(ResourceInjector.java:49)
    at org.jboss.weld.injection.producer.BeanInjectionTarget.<init>(BeanInjectionTarget.java:63)
    at org.jboss.weld.injection.producer.BeanInjectionTarget.createDefault(BeanInjectionTarget.java:47)
    at org.jboss.weld.manager.InjectionTargetFactoryImpl.chooseInjectionTarget(InjectionTargetFactoryImpl.java:113)
    at org.jboss.weld.manager.InjectionTargetFactoryImpl.createInjectionTarget(InjectionTargetFactoryImpl.java:86)
    at org.jboss.weld.bean.ManagedBean.<init>(ManagedBean.java:100)
    at org.jboss.weld.bean.ManagedBean.of(ManagedBean.java:80)
    at org.jboss.weld.bootstrap.AbstractBeanDeployer.createManagedBean(AbstractBeanDeployer.java:261)
    at org.jboss.weld.bootstrap.BeanDeployer.createClassBean(BeanDeployer.java:226)
    at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$2.doWork(ConcurrentBeanDeployer.java:74)
    at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$2.doWork(ConcurrentBeanDeployer.java:71)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:62)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:55)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    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)
    at org.jboss.threads.JBossThread.run(JBossThread.java:320)

15:17:38,896 ERROR [org.jboss.as.controller.management-operation] (management-handler-thread - 3) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "jpatest-1.0-SNAPSHOT")]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"jpatest-1.0-SNAPSHOT.war\".WeldStartService" => "Failed to start service
    Caused by: java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named 'pu' in deployment jpatest-1.0-SNAPSHOT.war for injection point private javax.persistence.EntityManager TestResource.entityManager"}}
15:17:38,911 ERROR [org.jboss.as.server] (management-handler-thread - 3) WFLYSRV0021: Deploy of deployment "jpatest-1.0-SNAPSHOT.war" was rolled back with the following failure message: 
{"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"jpatest-1.0-SNAPSHOT.war\".WeldStartService" => "Failed to start service
    Caused by: java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named 'pu' in deployment jpatest-1.0-SNAPSHOT.war for injection point private javax.persistence.EntityManager TestResource.entityManager"}}
15:17:38,911 INFO  [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-8) WFLYJCA0019: Stopped Driver service with driver-name = jpatest-1.0-SNAPSHOT.war_com.mysql.cj.jdbc.Driver_6_0
15:17:38,963 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-6) WFLYSRV0028: Stopped deployment jpatest-1.0-SNAPSHOT (runtime-name: jpatest-1.0-SNAPSHOT.war) in 62ms
[2018-01-29 03:17:39,010] Artifact jpatest:war exploded: Error during artifact deployment. See server log for details.
[2018-01-29 03:17:39,010] Artifact jpatest:war exploded: java.lang.Exception: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"jpatest-1.0-SNAPSHOT.war\".WeldStartService" => "Failed to start service
    Caused by: java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named 'pu' in deployment jpatest-1.0-SNAPSHOT.war for injection point private javax.persistence.EntityManager TestResource.entityManager"}}

将持久性单元注入CDI托管bean时出错。找不到名为“pu”的持久性单元

或者在TestResource类上使用@Vetoed时,entityManager上的指针为空。

我到底做错了什么,我不能用@PersistenceContext注入容器管理的entityManager?

我试图理解这一点,因为对其他人来说,这似乎是有效的。

请不要告诉我使用应用程序管理的事务,我可以使工作芽我需要容器管理的实体mnanager,所以我需要注入它

@PersistenceContext(UnitName=“”)

备注和编辑:

我使用的:Intellij、Wildfly、eclipselink、Java EE7、Maven、MySQL

此外,我的beans.xml中没有任何内容,只是将bean发现模式设置为ALL:

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                      http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    bean-discovery-mode="all">
</beans>

共有1个答案

裴畅
2023-03-14

由于您没有使用支持EntityManager注入的EJB,因此必须使用EntityManagerFactory来创建和销毁EntityManager。

EntityManagerFactory factory = Persistence.createEntityManagerFactory("pu");
EntityManager entityManager = factory.createEntityManager();

使用后,请始终关闭“EntityManager”

entityManager.close();

否则,将资源转换为EJB,添加@stateless

 类似资料:
  • 问题内容: 当前,我正在使用PersistenceContext注入EntityManager。EM被完美注入。 现在,我尝试装饰Bean,然后突然没有注入em。我得到一个NullPointerException。 我知道EJB和CDI是2个完全不同的管理器,所以一个都不知道另一个。我期望@PersistenceContext是EJB注入点,而@Inject是CDI。我应该怎么做才能解决这个问题并

  • 在包含DAO的第三部分jar库中,我在使用@PersistenceUnit注入EntityManagerFactory时遇到问题。 这是我的多模块maven项目结构。 我用CDI把所有的东西连接起来== 但是当我把@PersistenceUnit注释放在核心项目中时,它就不起作用了。(该字段为空) 当我在EJB项目中使用@PersistenceUnit时,一切正常。 我的坚持。xml文件位于EJB

  • 问题内容: 我的战争包含以下内容: persistence.xml: web.xml: 我的TestServlet类如下: package com.test.service; 调用get()方法时,我得到一个NullPointerException; 尚未注入EntityManager。关于我可能缺少的或如何诊断的任何建议?服务器日志中几乎没有。 我确定我在没有jboss-web.xml或web.

  • 问题内容: 我怎样才能像注入的依赖,,,,等的?在我的特定情况下,我需要通过以下方式注入Spring托管的: 但是,它没有注入,而是保留了null,导致。似乎,并且t也不起作用。 如何在验证器中注入服务依赖项,以便可以访问数据库? 问题答案: 在不被注入容器管理。你需要使其成为托管bean。使用Spring ,CDI @Named或JSF 代替,以便使其成为托管bean,从而有资格进行依赖项注入。

  • 我在Quarkus有一个微服务,它使用AxonIq框架实现CQRS/事件来源。我已经用Spring Boot做了,一切都没问题。我想在Quarkus中迁移它,但我在maven编译过程中出错,可能是因为Ioc。当CDI尝试创建服务时,我认为他可以注入Axon CommandGateway和QueryGateway。 配置 服务: 控制器: 屬地

  • 本文向大家介绍JS函数基本定义与用法示例,包括了JS函数基本定义与用法示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JS函数基本定义与用法。分享给大家供大家参考,具体如下: 运行结果: 函数调用时,没有参数限制,定义函数时,即使调用了参数个数不足,也不会报错,因为参数默认为undefined类型。 上面的三种函数的定义方法虽然不同,但是其对应的底层思想是相同的,其都相当于一个变量封装