Несколько источников данных Spring JPA

Я видел подобные вопросы здесь, но не смог найти ответ, который действительно работает для меня.

У меня есть 2 разных источника данных, каждый со своим менеджером транзакций и фабрикой менеджеров сущностей. Каждый из них определен в своем собственном классе конфигурации:

@Configuration
@ComponentScan({
"com.sprint.cst.data.v8p",
"com.sprint.v8p.data",
"com.sprint.v8p.data.util",
"com.sprint.v8p.toptower.repositories",
"com.sprint.v8p.toptower.util"})
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {
    "com.sprint.cst.data.v8p.repository",
    "com.sprint.v8p.repository",
    "com.sprint.eib.data" })
public class JpaConfiguration {

@Value("${cst.db.generateDdl:true}")
boolean generateDdl;
String ddlGenerationStrategy = "create-or-extend-tables";
@Value("${cst.db.showSql:true}")
boolean showSql;

private String[] defaultEntityPackagesToScan =
        new String[]{
        "com.sprint.v8p.domain",
        "com.sprint.v8p.toptower.domain",
        "com.sprint.cst.data.v8p.entity",
        "com.sprint.eib.entity"};

private JpaDialect jpaDialect = new EclipseLinkJpaDialect();


/// Primary JPA
@Primary
@Autowired
@Bean(name = "entityManagerFactory")
@Qualifier("entityManagerFactory")
public LocalContainerEntityManagerFactoryBean defaultEntityManagerFactory(DataSource dataSource) {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    //em.setPersistenceUnitName(UnitNames.DefaultPersistenceUnit);
    em.setDataSource(dataSource);
    em.setPackagesToScan(defaultEntityPackagesToScan);
    em.setJpaVendorAdapter(vendorAdapter());
    em.setJpaDialect(jpaDialect);
    em.setJpaProperties(defaultJpaProperties());
    return em;
}

@Primary
@Bean(name="transactionManager")
public PlatformTransactionManager defaultTransactionManager(
        EntityManagerFactory emf) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(emf);

    return transactionManager;
}

//'Datasource' Transaction Manager
//leveraged by ice events functionality; batch inserts/updates
@Autowired
@Bean(name="dsTransactionManager")
public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
    DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
    dataSourceTransactionManager.setDataSource(dataSource);
    return dataSourceTransactionManager;
}


/// Other Beans

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
}

@Bean
public PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor(){
    return new PersistenceAnnotationBeanPostProcessor();
}

А также:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    basePackages = {
        "com.sprint.cst.data.v8p.sp2.repository"},
    entityManagerFactoryRef="sp2EntityManagerFactory",
    transactionManagerRef="sp2TransactionManager")
public class JpaSp2Configuration {

@Value("${cst.db.generateDdl:true}")
boolean generateDdl;
//@Value("${cst.db.eclipselink.ddl-generation:'create-or-extend-tables'}")
String ddlGenerationStrategy = "create-or-extend-tables";
@Value("${cst.db.showSql:true}")
boolean showSql;

private String[] sp2EntityPackagesToScan =
        new String[]{
        "com.sprint.cst.data.v8p.sp2.entity"};

private JpaDialect jpaDialect = new EclipseLinkJpaDialect();

static final String sp2DataSourceJNDIName = "jdbc/cst-ds-sp2";

/// Secondary JPA
@Bean(name= "sp2EntityManagerFactory")
@Qualifier("sp2EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean sp2EntityManagerFactory(@Qualifier("sp2DataSource") DataSource sp2DataSource) {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setBeanName("sp2EntityManagerFactory");
    //em.setPersistenceUnitName(UnitNames.Sp2PersistenceUnit);
    em.setDataSource(sp2DataSource);
    em.setPackagesToScan(sp2EntityPackagesToScan);
    em.setJpaVendorAdapter(vendorAdapter());
    em.setJpaDialect(jpaDialect );
    em.setJpaProperties(defaultJpaProperties());
    return em;
}

@Autowired
@Bean(name="sp2TransactionManager")
@Qualifier("sp2TransactionManager")
public PlatformTransactionManager sp2TransactionManager(
        @Qualifier("sp2EntityManagerFactory") LocalContainerEntityManagerFactoryBean sp2EntityManagerFactory) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(sp2EntityManagerFactory.getNativeEntityManagerFactory());
    //transactionManager.setPersistenceUnitName(UnitNames.Sp2PersistenceUnit);
    return transactionManager;
}

Источники данных существуют в отдельной конфигурации источника данных. «Основные» функции работают нормально, функции «SP2» — нет. Например:

@Transactional("sp2TransactionManager")
@Override
public void saveCallHistory(CallHistoryObject callHistoryObject) {
    .
    .
    .

    SolutionInfoEntity solutionInfoResult = solutionInfoRepository.save(callHistoryObject.getSolutionInfoEntity());
    SolutionInfoEntity save = solutionInfoRepository.findOne(callHistoryObject.getSolutionInfoEntity().getSp2Id());

Объект «сохранить» здесь действительно возвращает результат, но на самом деле ничего не сохраняется в БД. Любые идеи? Я чувствую, что перепробовал почти все.


person jrichmond4    schedule 15.02.2016    source источник
comment
Возможный дубликат Spring Boot, Spring Data JPA с несколькими источниками данных   -  person Jens Schauder    schedule 14.11.2018


Ответы (2)


Убедитесь, что ваши репозитории находятся в разных пакетах (не менее 1 на каждый источник данных). А в той конфигурации, где у вас

@EnableJpaRepositories(basePackages = {
"com.sprint.cst.data.v8p.repository",
"com.sprint.v8p.repository",
"com.sprint.eib.data" })

для каждого соединения должны быть включены только эти репозитории.

Например, если источник данных (DS1) работает с пакетом

com.spring.ds1.repository

а dataSource (DS2) работает с пакетом

com.spring.ds2.repository

Конфигурация JpaRepositories будет выглядеть так

В конфигурации DS1

@EnableJpaRepositories(basePackages = {"com.spring.ds1.repository"})

В конфигурации DS2

@EnableJpaRepositories(basePackages = {"com.spring.ds2.repository"})

У меня были похожие проблемы с Cassandra, и с приведенной выше конфигурацией я смог ее решить.

person Shriram M.    schedule 15.02.2016

Сегодня я столкнулся с тем же состоянием и обнаружил, что методы, определенные в реализации JPARepository (SimpleJAPRepository.java), предоставленные spring, не будут работать во втором подключении к базе данных. Я объяснил свое открытие http://umeshrsharma.blogspot.in/2016/03/spring-data-jpa-with-multiple-database.html. Я могу ошибаться или отсутствовать в конфигурации. но все же моя основная функция JPA не работает, но функция определения пользователем работает. Если кто-то решил это, пожалуйста, объясните немного.

person umesh    schedule 04.03.2016