spring LocalContainerEntityManagerFactoryBean不能与persistentunitmanager一起使用

时间:2016-01-11 22:58:36

标签: spring hibernate jpa orm spring-orm

我想将LocalContainerEntityManagerFactoryBean与多个持久性单元一起使用。

的applicationContext.xml:

<bean id="jpaEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitManager" ref="jpaPersistenceUnitManager"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="true"/>
            <property name="generateDdl" value="false"/>
            <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
        </bean>
    </property>
</bean>

<bean id="jpaPersistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    <property name="defaultPersistenceUnitName" value="pu-user”/>
    <property name="persistenceXmlLocations">
        <list>
            <value>classpath*:META-INF/persistence-user.xml</value>
            <value>classpath*:META-INF/persistence-customer.xml</value>
        </list>
    </property>
    <property name="dataSources">
        <map>
            <entry key=“userDataSource" value-ref=“userDataSource"/>
            <entry key="customerDataSource" value-ref=“customerDataSource"/>
        </map>
    </property>
    <property name="defaultDataSource" ref=“userDataSource"/>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" primary="true">
    <property name="entityManagerFactory" ref="jpaEntityManagerFactory"/>
</bean>

<tx:annotation-driven proxy-target-class="true"/>

<context:component-scan base-package="simple.user.persistence"/>
<context:component-scan base-package="simple.customer.persistence"/>

持久性xmls定义如下:

<persistence-unit name="pu-user" transaction-type="RESOURCE_LOCAL">
    <jta-data-source>userDataSource</jta-data-source>
    <non-jta-data-source>userDataSource</non-jta-data-source>
</persistence-unit>

DataSources定义如下:

<bean id="userDataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/user"/>
    <property name="username" value="user"/>
    <property name="password" value="password"/>
    <property name="maxTotal" value="32"/>
    <property name="maxIdle" value="32"/>
    <property name="validationQuery" value="select 1"/>
</bean>

UserRepository和CustomerRepository定义如下:

package simple.user.persistence;

@Repository
public class UserRepository {
   @PersistenceContext(unitName="pu-user”)
   EntityManager em;

   @Transactional
   User createUser(User user) {
       em.persist(user);
   }
}

当我运行单元测试时,我遇到以下异常。

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'pu-customer' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.orm.jpa.EntityManagerFactoryUtils.findEntityManagerFactory(EntityManagerFactoryUtils.java:139)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findNamedEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:556)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:538)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:707)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:680)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:354)
... 60 more

查看EntityManagerFactoryUtils的源代码。第132行的findEntityManagerFactory方法清楚地只比较defaultPersistentUnitName并忽略在DeafultPersistentUnitManager中定义的其他持久单元名称。这对我来说就像一个bug。请让我知道您的想法。

https://github.com/spring-projects/spring-framework/blob/master/spring-orm/src/main/java/org/springframework/orm/jpa/EntityManagerFactoryUtils.java

1 个答案:

答案 0 :(得分:0)

当我需要多个持久性单元时,我创建了多个LocalContainerEntityManagerFactoryBean,然后每个LocalContainerEntityManagerFactoryBean都有一个对应的JpaTransactionManager。

一个涟漪是,如果您有多个事务管理器,则需要在@Transactional注释中命名要使用的事务管理器。

我想如果您需要在单个事务中访问两个持久性单元,您需要一个JTA事务管理器来结合2个JPA事务管理器 - 但不确定您的要求是什么。