JPA如何定义哪个持久化单元用于特定实体类
我正在使用应用程序,需要多个数据库连接。我创建了AbstractDao.class,我想使用为特定实体类定义的EntityManager。在我的示例中,我定义了两种类型的实体:OracleEmployeeEntity和MySQLEmployeeEntity。如何在AbstractDao中定义EntityManager以为正确的实体使用正确的实例?在我目前的配置下面,当我运行使用两个dbs的NullPointerException引发测试。JPA如何定义哪个持久化单元用于特定实体类
AbstractDao.class:
@Transactional
public abstract class AbstractDao<T, K extends Serializable> implements IDao<T, K> {
@PersistenceContext
protected EntityManager entityManager;
private Class<T> domainClass;
@Override
public T save(T entity) {
entityManager.persist(entity);
return entity;
}
@Override
@SuppressWarnings("unchecked")
public T getOne(K id) {
return entityManager.getReference(getDomainClass(), id);
}
[...]
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="default" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.example.database.tests.entities.OracleEmployeeEntity</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="javax.persistence.jdbc.user" value="test_user"/>
<property name="javax.persistence.jdbc.password" value="test_user"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521/xe"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
<property name="hibernate.flushMode" value="FLUSH_AUTO"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
<persistence-unit name="db1" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.example.database.tests.entities.OracleEmployeeEntity</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="javax.persistence.jdbc.user" value="test_user"/>
<property name="javax.persistence.jdbc.password" value="test_user"/>
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521/xe"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/>
<property name="hibernate.flushMode" value="FLUSH_AUTO"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
<persistence-unit name="db2" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.example.database.tests.entities.MySqlEmployeeEntity</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/employees"/>
<property name="hibernate.flushMode" value="FLUSH_AUTO"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
测试部分:
//db variable defined in @Before (jUnit)
@Test
public void testShouldCompareDataFromDifferentDatabases() {
//given
MySQLDatabase mySQLDatabase = new MySQLDatabase();
//when
long oracleCount = db.getEmployeeDao().count();
long mySqlCount = mySQLDatabase.getEmployeeDao().count();
//then
assertNotEquals(oracleCount, mySqlCount);
}
堆栈跟踪:
java.lang.NullPointerException
at com.example.database.base.AbstractDao.count(AbstractDao.java:74)
at com.example.database.tests.assertions.JpaTest.testShouldCompareDataFromDifferentDatabases(JpaTest.java:166)
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$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at com.example.core.tests.testRunners.core.CustomRunAfters.evaluate(CustomRunAfters.java:39)
at com.example.core.tests.testRunners.ParallelTestClassRunner.run(ParallelTestClassRunner.java:36)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
@PersistenceContext
有unitName
属性,因为你还没有指定单元名称默认为空string.you必须指定要使用
@PersistenceContext(unitName= "someunitname")
protected EntityManager entityManager;
不幸的是,仍然得到了相同的异常。我读过@PersistenceContext不要创建EntityManager的实例,也许这是一个问题?还有什么,AbstractDao是一个普通的类,具体的。持久化单元的硬编码我想进入具体的实现。 – pwoj
@pwoj,你的异常堆栈跟踪在哪里?这是基本的帮助 –
详细的异常,请在单元名。你使用什么服务器?什么样的应用程序/环境? –
stacktrace更新了部分测试 – pwoj