persistence.xml 文件中的多个持久性单元与 JPA 2.1

Multiple persistence unit in persistence.xml file with JPA 2.1

我正在尝试部署一个连接到 Oracle 数据库和 MySQL 的应用程序。我正在使用 JPA 2.1、Hibernate 4.3.7、Spring、Spring Data 和 WildFly 8.2,但在部署应用程序时出现一些错误。 Eclipse 显示错误。他说我不能使用多个持久性单元。我很困惑,因为我在网上发现一些文章显示文件具有多个持久性单元。 Like this one.

首先是我的 persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
             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://www.oracle.com/webfolder/technetwork/jsc/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="authwsPU" transaction-type="JTA">
        <jta-data-source>java:/datasource/authwsds</jta-data-source>

        ..My MySQL mapping classes...

        <properties>
            <!-- MySQL -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>

            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.id.new_generator_mappings" value="true"/>
            <property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/authwsEMF" />
        </properties>
    </persistence-unit>

    <persistence-unit name="antaresPU" transaction-type="JTA">
        <jta-data-source>java:/datasource/antaresds</jta-data-source>

        ...My Oracle mapping classes...

        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.id.new_generator_mappings" value="true"/>
            <property name="jboss.entity.manager.factory.jndi.name" value="java:jboss/antaresEMF" />
        </properties>
    </persistence-unit>
</persistence>

我也在 jboss-web.xml 上进行了更改:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee
                               http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">

    <context-root>/authws</context-root>

    <persistence-context-ref id="autenticacaoCtx">
        <persistence-context-ref-name>auth_ws/authEMF</persistence-context-ref-name>
        <persistence-unit-name>authwsPU</persistence-unit-name>
    </persistence-context-ref>

    <persistence-context-ref id="antaresCtx">
        <persistence-context-ref-name>auth_ws/antaresEMF</persistence-context-ref-name>
        <persistence-unit-name>antaresPU</persistence-unit-name>
    </persistence-context-ref>
</jboss-web>

和错误。 Eclipse,警告过我,但我忽略了。:

Multiple persistence units defined - only the first persistence unit will be recognized

然后我部署了,WildFly 显示了这个错误:

Caused by: java.lang.IllegalArgumentException: JBAS011470: Persistence unitName was not specified and there are 2 persistence unit definitions in application deployment deployment "authws.war".  Either change the application deployment to have only one persistence unit definition or specify the unitName for each reference to a persistence unit.
    at org.jboss.as.jpa.container.PersistenceUnitSearch.ambiguousPUError(PersistenceUnitSearch.java:187)
    at org.jboss.as.jpa.container.PersistenceUnitSearch.findWithinDeployment(PersistenceUnitSearch.java:153)
    at org.jboss.as.jpa.container.PersistenceUnitSearch.findPersistenceUnitSupplier(PersistenceUnitSearch.java:75)
    at org.jboss.as.jpa.container.PersistenceUnitSearch.resolvePersistenceUnitSupplier(PersistenceUnitSearch.java:64)
    at org.jboss.as.jpa.processor.JPAAnnotationProcessor.getPersistenceUnit(JPAAnnotationProcessor.java:372)
    at org.jboss.as.jpa.processor.JPAAnnotationProcessor.getBindingSource(JPAAnnotationProcessor.java:296)
    at org.jboss.as.jpa.processor.JPAAnnotationProcessor.processMethod(JPAAnnotationProcessor.java:206)
    at org.jboss.as.jpa.processor.JPAAnnotationProcessor.processPersistenceAnnotations(JPAAnnotationProcessor.java:143)
    at org.jboss.as.jpa.processor.JPAAnnotationProcessor.deploy(JPAAnnotationProcessor.java:100)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:159) [wildfly-server-8.2.0.Final.jar:8.2.0.Final]
    ... 5 more

更新

我正在用更多细节更新问题。首先,我在其中为 Spring Data:

创建 EntityManagersFactory 的文件
<jee:jndi-lookup jndi-name="java:jboss/poEMF" id="poEntityManagerFactory" expected-type="javax.persistence.EntityManagerFactory" />
<jpa:repositories base-package="br.com.po.dao" entity-manager-factory-ref="poEntityManagerFactory"  />

<jee:jndi-lookup jndi-name="java:jboss/antaresEMF" id="antaresEntityManagerFactory" expected-type="javax.persistence.EntityManagerFactory" />
<jpa:repositories base-package="br.com.antares.dao" entity-manager-factory-ref="antaresEntityManagerFactory" />

在线阅读更多相关信息,我发现问题可能出在注解 @PersistenceUnit 的规范上,我必须在其中指定 unitName,例如 @PersistenceUnit(unitName="defaultPersistenceUnit")但是,如果我使用 Spring 数据,我该怎么做?

例如,您可以在您的@Configuration 文件中使用@EnableJpaRepositories(如果您使用的是Bean 配置),如下所示:

一个配置文件:

 @Configuration
 @EnableTransactionManagement
 @EnableJpaRepositories(
       basePackages = {"com.yourpackage.xxxx"},
       entityManagerFactoryRef = "entityManagerFactory1",
       transactionManagerRef = "transactionManager")
       public class FirstPersistenceContextConfig {}
....

还有第二个配置文件:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
       basePackages = {"com.yourpackage.yyyy"},
       entityManagerFactoryRef = "entityManagerFactory2",
       transactionManagerRef = "transactionManager")
       public class SecondPersistenceContextConfig {}
...

不知道你的问题有没有解决

如果您使用的是 XML 配置,试试这个:

<jpa:repositories base-package="[repository]" 
    entity-manager-factory-ref="mysqlManager" transaction-manager-ref="mysqlTransaction"/>

<jpa:repositories base-package="[repository]" 
    entity-manager-factory-ref="oracleManager" transaction-manager-ref="oracleTransaction"/>

<bean id="mysqlDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <!-- MySQL Configuration Connection -->
</bean>        

<bean id="mysqlTransaction" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="mysqlManager" />
</bean>

<bean id="mysqlManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">        
    <property name="dataSource" ref="mysqlDataSource" />
    <property name="persistenceUnitName" value="mysqlPU" />
    <property name="packagesToScan" value="lh.ast.model" />
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>

    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
            <property name="showSql" value="true" />
        </bean>
    </property>

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.format_sql">true</prop>                
            <prop key="hibernate.hbm2ddl.auto">update</prop>
        </props>
    </property>     
</bean>

<bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <!-- Oracle Configuration Connection -->
</bean>

<bean id="oracleTransaction" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="oracleManager" />
</bean>

<bean id="oracleManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">        
    <property name="dataSource" ref="oracleDataSource" />
    <property name="persistenceUnitName" value="oraclePU" />
    <property name="packagesToScan" value="[your entity package]" />
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>

    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
            <property name="showSql" value="true" />
        </bean>
    </property>

    <property name="jpaProperties">
        <props>
            <prop key="hibernate.format_sql">true</prop>    
            <prop key="hibernate.hbm2ddl.auto">update</prop>            
        </props>
    </property> 
</bean>