2017-09-19 36 views
0

我正在使用應用程序,需要多個數據庫連接。我創建了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) 
+0

詳細的異常,請在單元名。你使用什麼服務器?什麼樣的應用程序/環境? –

+0

stacktrace更新了部分測試 – pwoj

回答

0

@PersistenceContextunitName屬性,因爲你還沒有指定單元名稱默認爲空string.you必須指定要使用

@PersistenceContext(unitName= "someunitname") 
protected EntityManager entityManager; 
+0

不幸的是,仍然得到了相同的異常。我讀過@PersistenceContext不要創建EntityManager的實例,也許這是一個問題?還有什麼,AbstractDao是一個普通的類,具體的。持久化單元的硬編碼我想進入具體的實現。 – pwoj

+0

@pwoj,你的異常堆棧跟蹤在哪裏?這是基本的幫助 –

相關問題