在最基本的示例中,无法使用@PersistenceContext注入EntityManager [英] Cant inject EntityManager With @PersistenceContext in most basic example
问题描述
要使用实体管理器的PersistenceContext注入来测试JPA,我有一个具有以下结构的基本示例项目: 人物实体:
To test JPA with PersistenceContext injection of entity manager I have basic example project with following structure: 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 + '\'' +
'}';
}
}
其余配置:
@ApplicationPath("/api")
public class RestConfig extends Application {
}
测试休息端点:
@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.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 defined in my 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>
具有战争结构的项目结构:
Project structure with war structure:
然后在我的pom.xml里面:
And following inside of my 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上运行,我得到的输出是:
All of this is running on latest stable Wildfly, output that i get is :
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上的空指针.
Or null pointer on entityManager when i use @Vetoed on TestResource class.
我无法使用@PersistenceContext注入容器托管的EntityManager到底是什么错误?
我试图理解这一点,因为对于其他所有人来说,这似乎是可行的.
Im trying to understand this since for everyone else this seems to be working.
请不要告诉我使用应用程序管理的事务,我可以让工作容器成为需要容器管理的EntityMnanager的对象,所以我需要注入
@PersistenceContext(unitName =")
@PersistenceContext(unitName="")
注意事项和
我使用的是: Intellij,Wildfly,eclipselink,Java EE7,Maven,MySQL
What i use: Intellij,Wildfly,eclipselink,Java EE7,Maven,MySQL
此外,我的beans.xml中没有任何内容,只是将bean发现模式设置为全部:
In addition my beans.xml has nothing in it just beans discovery mode set to 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>
我在Resource类上尝试了多个注释,但始终无法注入em:
I have tried multiple annotation on my Resource class, always failed to inject em:
推荐答案
由于您没有使用支持EntityManager
注入的EJB,因此必须使用EntityManagerFactory
创建和销毁EntityManager.
Since you are not using a EJB, which supports EntityManager
injection, you have to use the EntityManagerFactory
to create and destroy an EntityManager.
EntityManagerFactory factory = Persistence.createEntityManagerFactory("pu");
EntityManager entityManager = factory.createEntityManager();
使用它后,始终关闭"entityManager"
After using it always close the "entityManager"
entityManager.close();
否则,将您的资源转换为EJB,添加@Stateless
.
Otherwise turn your resource into an EJB, adding @Stateless
.
这篇关于在最基本的示例中,无法使用@PersistenceContext注入EntityManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!