在相同XML文件中的JPA中配置多个持久性单元

时间:2012-04-26 07:44:52

标签: spring jpa

我有两个数据库A,B.我在数据库A中有一个名为asample的表,在数据库B中有一个bsample表。现在我想将数据从B数据库的bsample表传输到A数据库的asample表。为此,我必须在persistence.xml文件中使用两个持久性单元。我正在使用JPA,Spring。我是jpa的新手。任何人都可以告诉我如何实现这一目标。

如果我使用下面提到的代码,我将收到此异常:

ERROR: org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0' defined in ServletContext resource [/WEB-INF/classes/META-INF/spring-context/dao-DB1.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mediationEntityManagerFactory' defined in ServletContext resource [/WEB-INF/classes/META-INF/spring-context/dao-DB2.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: DB2] Unable to build EntityManagerFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:710)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:410)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:442)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:458)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:339)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:306)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    at javax.servlet.GenericServlet.init(GenericServlet.java:160)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1266)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1185)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1080)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5015)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5302)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mediationEntityManagerFactory' defined in ServletContext resource [/WEB-INF/classes/META-INF/spring-context/dao-DB2.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: DB2] Unable to build EntityManagerFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:398)
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:275)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:79)
    at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:70)
    at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:99)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1439)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1408)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 26 more
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: DB2] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:900)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:225)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:308)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
    ... 41 more

我在persistence.xml文件中放置了两个持久性单元,我有两个dao文件作为dao-DB1.xml,dao-DB2.xml,我正在配置如答案中提到的EntityManager。

2 个答案:

答案 0 :(得分:5)

Spring提供PersistenceUnitManager作为中央存储库并避免(可能很昂贵的)持久性单元发现过程。默认实现允许指定多个位置。

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
  <property name="persistenceXmlLocation">
    <list>
     <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
     <value>classpath:/my/package/**/custom-persistence.xml</value>
     <value>classpath*:META-INF/persistence.xml</value>
    </list>
  </property>

</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="persistenceUnitManager" ref="pum"/>
</bean>

来源 - Spring orm jpa

答案 1 :(得分:3)

示例persistence.xml包含两个数据源,在本例中是两个Oracle数据库,使用hibernate作为JPA提供程序:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="DB1" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@server:port:sid"/>
        <property name="javax.persistence.jdbc.user" value="username"/>
        <property name="javax.persistence.jdbc.password" value="password"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
    </properties>
</persistence-unit>
<persistence-unit name="DB2" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <!-- same as above, different properties -->
    </properties>
</persistence-unit>
</persistence>

如果要通过spring配置持久性单元,可以执行以下操作:

<bean id="DB1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@server:port:sid"/>
    <property name="username" value="username"/>
    <property name="password" value="password"/>
</bean>

<bean id="DB2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <!-- same as above, different properties --> 
</bean>

<bean id="DB1entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="DB1-unit"/>
    <property name="dataSource" ref="DB1"/>
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
        </props>
    </property>
</bean>

<bean id="DB2entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="DB2-unit"/>
    <property name="dataSource" ref="DB2"/>
    <!-- same as above -->
</bean>