2012-03-27 6 views
1

Я пытаюсь использовать Spring Data JPA с двумя базами данных в проекте. Но исключение срабатывает, когда я пытаюсь запустить приложение:несколько баз данных с данными Spring Data JPA

07:21:47.734 [main] ERROR o.s.web.context.ContextLoader - Context initialization failed 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'deviceRepository': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.persistence.EntityManagerFactory] is defined: expected single bean but found 2 
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:342) ~[spring-orm-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) ~[spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) ~[spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) ~[spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
... 

Вот мой applicationContext.xml

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource1"> 
    <property name="driverClassName" value="${database.driverClassName}"/> 
    <property name="url" value="${database.url1}"/> 
    <property name="username" value="${database.username1}"/> 
    <property name="password" value="${database.password1}"/> 
    <property name="testOnBorrow" value="true"/> 
    <property name="testOnReturn" value="true"/> 
    <property name="testWhileIdle" value="true"/> 
    <property name="timeBetweenEvictionRunsMillis" value="1800000"/> 
    <property name="numTestsPerEvictionRun" value="3"/> 
    <property name="minEvictableIdleTimeMillis" value="1800000"/> 
    <property name="validationQuery" value="SELECT 1"/> 
</bean> 
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager1"> 
    <property name="entityManagerFactory" ref="entityManagerFactory1"/> 
</bean> 
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager1"/> 
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory1"> 
    <property name="persistenceUnitName" value="persistenceUnit1"/> 
    <property name="dataSource" ref="dataSource1"/> 
</bean> 

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource2"> 
    <property name="driverClassName" value="${database.driverClassName}"/> 
    <property name="url" value="${database.url2}"/> 
    <property name="username" value="${database.username2}"/> 
    <property name="password" value="${database.password2}"/> 
    <property name="testOnBorrow" value="true"/> 
    <property name="testOnReturn" value="true"/> 
    <property name="testWhileIdle" value="true"/> 
    <property name="timeBetweenEvictionRunsMillis" value="1800000"/> 
    <property name="numTestsPerEvictionRun" value="3"/> 
    <property name="minEvictableIdleTimeMillis" value="1800000"/> 
    <property name="validationQuery" value="SELECT 1"/> 
</bean> 
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager2"> 
    <property name="entityManagerFactory" ref="entityManagerFactory2"/> 
</bean> 
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager2"/> 
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory2"> 
    <property name="persistenceUnitName" value="persistenceUnit2"/> 
    <property name="dataSource" ref="dataSource2"/> 
</bean> 

Вот мой DAO интерфейс:

@Repository 
public interface DeviceRepository extends JpaRepository<Device, DevicePK>, 
    JpaSpecificationExecutor<Device> { 
} 

Я я много читал о @PersistenceContext, но я никогда не видел использования с JpaRepository.

ответ

1

Ну, у вас есть 2 сущ. Я никогда не использовал JPARepository, но если он работает близко к его счетным частям по пружинным данным для nosql, Spring повысит класс и, вероятно, добавит EM на него. Ваша проблема в том, что у вас 2 объявленных EM.

Посмотрите на пружинных-JPA документы, они покажут вам, как настроить хранилище для того, как вы можете добавить конкретные EMF к вашим сделкам РЕПО

0

Длинная история короткой:

Вы должны создать Заказная реализация этого интерфейса и реализация должна содержать диспетчер объектов объявлен как:

@PersistenceContext(unitName = "persistenceUnit1") 
    private EntityManager entityManager; 

, если вы хотите использовать единицы сохранения 1.

Проверьте это: http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/repositories.html#repositories.custom-implementations, он также имеет примеры и пример 1.17 (немного по странице) реализует интерфейс и имеет в нем диспетчер сущностей, и этот диспетчер объектов передается супер-конструктору.

Вы также можете взглянуть на Spring Data - JPA, customizing Repository not working, у него есть реализация интерфейса, который расширяет JpaRepository, и он также имеет объявленный в реализации сущность-менеджер. Просто добавьте unitName в аннотацию @PersistenceContext и попробуйте ее таким образом.

Возможно, вам не нужны какие-либо пользовательские методы (так что ваш интерфейс может быть пустым), но вам нужен конструктор, который передает управление сущностью и все, что возится с расширением вашего собственного интерфейса, чтобы обойти поведение автоматической проводки по умолчанию.