我想将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。请让我知道您的想法。
答案 0 :(得分:0)
当我需要多个持久性单元时,我创建了多个LocalContainerEntityManagerFactoryBean,然后每个LocalContainerEntityManagerFactoryBean都有一个对应的JpaTransactionManager。
一个涟漪是,如果您有多个事务管理器,则需要在@Transactional注释中命名要使用的事务管理器。
我想如果您需要在单个事务中访问两个持久性单元,您需要一个JTA事务管理器来结合2个JPA事务管理器 - 但不确定您的要求是什么。