несколько баз данных с Spring Data JPA - PullRequest
1 голос
/ 27 марта 2012

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

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]
...

Вот мое приложениеContext.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.

Ответы [ 3 ]

0 голосов
/ 22 июня 2014

Короче говоря:

Вы должны создать пользовательскую реализацию этого интерфейса, и эта реализация должна содержать менеджер сущностей, объявленный как:

    @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, настраивающий Репозиторий не работает , он имеет реализацию интерфейса, расширяющего JpaRepository, а также имеет менеджер сущностей, объявленный в реализации. Просто добавьте unitName к аннотации @PersistenceContext и попробуйте его таким образом.

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

0 голосов
/ 27 сентября 2018

Один из двух источников данных должен быть определен как первичный.

<bean> имеет первичный атрибут, который может быть установлен в true или false:

<bean primary="true|false"/>

Обычно в @Configuration аннотация @Primary помещается в:

EntityManager DataSource TransactionManager

Так что вы можете попробовать добавить primary="true"

к следующим бобам:

dataSource1 transactionManager1 entityManagerFactory1

0 голосов
/ 27 марта 2012

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

Посмотрите документы spring-jpa, они покажут вам, как настроить репозиторий и как вы можете добавить определенные EMF в свои репо

...