1

我目前正在尝试让 Spring Data JPA 与两个 DataSources 以及两个 EntityManagers 一起工作。我的存储库都继承自自定义基类“BaseRepositoryImpl”。

问题: 我总是遇到以下异常:

org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No unique bean of type [javax.persistence.EntityManagerFactory] is defined: 
expected single bean but found 2: entityManagerFactory1,entityManagerFactory2

问题: 如何告诉我的自定义 RepositoryFactory 使用哪个 EntityManagerFactory?

这是我的 Spring 配置:

<jpa:repositories base-package="package1" transaction-manager-ref="..."
  factory-class="MyFactoryBean"
  entity-manager-factory-ref="entityManagerFactory1"/>  

<bean id="dataSource1" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="..." />
</bean>

<bean id="entityManagerFactory1" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource1" />
  <property name="persistenceUnitName" value="unit1" />   
  ...
</bean>

<jpa:repositories base-package="package2" transaction-manager-ref="..."
  factory-class="MyFactoryBean"
  entity-manager-factory-ref="entityManagerFactory2"/>  

<bean id="dataSource2" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="..." />
</bean>

<bean id="entityManagerFactory2" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource2" />
  <property name="persistenceUnitName" value="unit2" />   
  ...
</bean>

“MyFactoryBean”类的实现与http://docs.spring.io/spring-data/jpa/docs/1.4.x/reference/htmlsingle/#repositories.custom-behaviour-for-all-repositories中的描述完全相同。

Spring 似乎忽略了配置“entity-manager-factory-ref”,至少在使用自定义 RepositoryFactory 时是这样。

有什么提示吗?

4

1 回答 1

1

实体管理器工厂用于为不同的持久化单元创建实体管理器。您声明您的实体管理器 bean,然后将实体管理器工厂 bean 作为它的类。

这对我有用:

<tx:annotation-driven transaction-manager="transactionManager" />

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

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

<bean id="defaultDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${hibernate.connection.driver_class}"/>
    <property name="url" value="${db.default.url}"/>
    <property name="username" value="${db.default.username}"/>
    <property name="password" value="${db.default.password}"/>
</bean>

<bean id="defaultEntityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="defaultDataSource"/>
    <property name="persistenceUnitName" value="defaultPersistenceUnit"/>
</bean>

<bean id="otherDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${hibernate.connection.driver_class}"/>
    <property name="url" value="${db.other.url}"/>
    <property name="username" value="${db.other.username}"/>
    <property name="password" value="${db.other.password}"/>
</bean>

<bean id="otherEntityManager" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="otherDataSource"/>
    <property name="persistenceUnitName" value="otherPersistenceUnit"></property>
</bean>

然后,当您实现数据访问类时,只需声明:

@Repository
@Transactional
public class MyDAOImpl implements MyDAO
{
    @PersistenceContext(unitName = "defaultPersistenceUnit")
    private EntityManager entityManager;
}

对于使用其他持久性单元的 DAO:

@Repository
@Transactional
public class MyOtherDAOImpl implements MyOtherDAO
{
    @PersistenceContext(unitName = "otherPersistenceUnit")
    private EntityManager entityManager;
}
于 2014-06-22T04:24:22.643 回答