spring boot secondary datasource with primary auto

2019-04-16 20:08发布

i am trying to configure two jpa datasource , i did same as this example , every thing is good but is it possible to keep the auto configuration done automatically and just add a new one without having to create LocalContainerEntityManagerFactoryBean manually.

 @Primary
    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

@Bean
PlatformTransactionManager transactionManager() {
    return new JpaTransactionManager(entityManagerFactory().getObject());
}

@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
    jpaVendorAdapter.setGenerateDdl(false);

    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();

    factoryBean.setDataSource(dataSource());
    factoryBean.setJpaVendorAdapter(jpaVendorAdapter);

    factoryBean.setPackagesToScan("com.xxxxxxxx.common.domain","com.xxxxxxx.tekram.cdrserver.domain");

    return factoryBean;
}

1条回答
Root(大扎)
2楼-- · 2019-04-16 20:43

I'm not really sure about what's your concrete problem or what you wish to acomplish, but I'll show you how I've used two dataSources with Spring Boot using the auto configuration features:

Create config for every data source (in separate classes only to better reading):

PrimaryDbConfig.java

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.aoc.dao", entityManagerFactoryRef = "entityManager", transactionManagerRef = "transactionManager")
public class PrimaryDBConfiguration {

 @Bean(name = "dataSource")      
 @Primary
 @ConfigurationProperties(prefix = "primary.datasource")
 public DataSource dataSource() {
      return DataSourceBuilder.create().build();
 }

 @PersistenceContext(unitName = "primary")   
 @Primary
 @Bean(name = "entityManager")
 public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
      return builder.dataSource(dataSource())
              .persistenceUnit("primary")                 
              .packages("com.aoc.model")
              .build();
 }

}

SecondaryDbConfig.java

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.aoc.dao", entityManagerFactoryRef = "secondaryEntityManager", transactionManagerRef = "secondaryTransactionManager")
public class SecondaryDBConfiguration {
  @Bean
  @ConfigurationProperties(prefix = "secondary.datasource")
   public DataSource secDataSource() {
        return DataSourceBuilder.create().build();
   }
  @PersistenceContext(unitName = "secondary")
  @Bean(name = "secondaryEntityManager")
  public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
       return  builder.dataSource(secDataSource())                 
               .persistenceUnit("secondary")
               .packages("com.aoc.siri")
               .build();
  }

  @Bean(name = "secondaryTransactionManager")
   public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
         JpaTransactionManager tm = new JpaTransactionManager();
         tm.setEntityManagerFactory(entityManagerFactory(builder).getObject());
         tm.setDataSource(secDataSource());
         return tm;
   }       
}

Anotate every DAO with it's respective PersistenceContext unitName:

OneDaoImpl.java

@Repository(value = "OneDaoImpl")
public class OneDaoImpl {

@PersistenceContext(unitName="primary")
private EntityManager manager;

public List<AplicacioMsc> getAllOne() {     
    return (List<One>) manager.createQuery("FROM ONE", One.class).getResultList();
}
}

AnotherDaoImpl.java

@Repository(value = "anotherDaoImpl")
public class AnotherDaoImpl {

@PersistenceContext(unitName = "secondary")
private EntityManager manager;


public List<Producte> getAllAnother() {     
    return (List<Another>) manager.createQuery("FROM Another", Another.class).getResultList();
}
}

Then in your src/main/resources/application.properties

primary.datasource.driver-class-name=...
primary.datasource.url=...
primary.datasource.username=xxx
primary.datasource.password=yyy

secondary.datasource.driver-class-name=...
secondary.datasource.url=...
secondary.datasource.username=zzz
secondary.datasource.password=xxx

As you probably know if you are using the recommended Spring Boot packages naming with these classes and anotations you should be able to use that two dataSources at the same time.

查看更多
登录 后发表回答