Spring Boot, Spring Data JPA with multiple DataSources

116,412

Solution 1

There is another way to have multiple dataSources by using @EnableAutoConfiguration and application.properties.

Basically put multiple dataSource configuration info on application.properties and generate default setup (dataSource and entityManagerFactory) automatically for first dataSource by @EnableAutoConfiguration. But for next dataSource, create dataSource, entityManagerFactory and transactionManager all manually by the info from property file.

Below is my example to setup two dataSources. First dataSource is setup by @EnableAutoConfiguration which can be assigned only for one configuration, not multiple. And that will generate 'transactionManager' by DataSourceTransactionManager, that looks default transactionManager generated by the annotation. However I have seen the transaction not beginning issue on the thread from scheduled thread pool only for the default DataSourceTransactionManager and also when there are multiple transaction managers. So I create transactionManager manually by JpaTransactionManager also for the first dataSource with assigning 'transactionManager' bean name and default entityManagerFactory. That JpaTransactionManager for first dataSource surely resolves the weird transaction issue on the thread from ScheduledThreadPool.

Update for Spring Boot 1.3.0.RELEASE

I found my previous configuration with @EnableAutoConfiguration for default dataSource has issue on finding entityManagerFactory with Spring Boot 1.3 version. Maybe default entityManagerFactory is not generated by @EnableAutoConfiguration, once after I introduce my own transactionManager. So now I create entityManagerFactory by myself. So I don't need to use @EntityScan. So it looks I'm getting more and more out of the setup by @EnableAutoConfiguration.

Second dataSource is setup without @EnableAutoConfiguration and create 'anotherTransactionManager' by manual way.

Since there are multiple transactionManager extends from PlatformTransactionManager, we should specify which transactionManager to use on each @Transactional annotation

Default Repository Config

@Configuration
@EnableTransactionManagement
@EnableAutoConfiguration
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactory",
        transactionManagerRef = "transactionManager",
        basePackages = {"com.mysource.repository"})
public class RepositoryConfig {
    @Autowired
    JpaVendorAdapter jpaVendorAdapter;

    @Autowired
    DataSource dataSource;

    @Bean(name = "entityManager")
    public EntityManager entityManager() {
        return entityManagerFactory().createEntityManager();
    }

    @Primary
    @Bean(name = "entityManagerFactory")
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource);
        emf.setJpaVendorAdapter(jpaVendorAdapter);
        emf.setPackagesToScan("com.mysource.model");
        emf.setPersistenceUnitName("default");   // <- giving 'default' as name
        emf.afterPropertiesSet();
        return emf.getObject();
    }

    @Bean(name = "transactionManager")
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager tm = new JpaTransactionManager();
        tm.setEntityManagerFactory(entityManagerFactory());
        return tm;
    }
}

Another Repository Config

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "anotherEntityManagerFactory",
        transactionManagerRef = "anotherTransactionManager",
        basePackages = {"com.mysource.anothersource.repository"})
public class AnotherRepositoryConfig {
    @Autowired
    JpaVendorAdapter jpaVendorAdapter;

    @Value("${another.datasource.url}")
    private String databaseUrl;

    @Value("${another.datasource.username}")
    private String username;

    @Value("${another.datasource.password}")
    private String password;

    @Value("${another.dataource.driverClassName}")
    private String driverClassName;

    @Value("${another.datasource.hibernate.dialect}")
    private String dialect;

    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl, username, password);
        dataSource.setDriverClassName(driverClassName);
        return dataSource;
    }

    @Bean(name = "anotherEntityManager")
    public EntityManager entityManager() {
        return entityManagerFactory().createEntityManager();
    }

    @Bean(name = "anotherEntityManagerFactory")
    public EntityManagerFactory entityManagerFactory() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", dialect);

        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource());
        emf.setJpaVendorAdapter(jpaVendorAdapter);
        emf.setPackagesToScan("com.mysource.anothersource.model");   // <- package for entities
        emf.setPersistenceUnitName("anotherPersistenceUnit");
        emf.setJpaProperties(properties);
        emf.afterPropertiesSet();
        return emf.getObject();
    }

    @Bean(name = "anotherTransactionManager")
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager(entityManagerFactory());
    }
}

application.properties

# database configuration
spring.datasource.url=jdbc:h2:file:~/main-source;AUTO_SERVER=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.continueOnError=true
spring.datasource.initialize=false

# another database configuration
another.datasource.url=jdbc:sqlserver://localhost:1433;DatabaseName=another;
another.datasource.username=username
another.datasource.password=
another.datasource.hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect 
another.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver

Choose proper transactionManager for @Transactional annotation

Service for first datasource

@Service("mainService")
@Transactional("transactionManager")
public class DefaultDataSourceServiceImpl implements DefaultDataSourceService       
{

   //

}

Service for another datasource

@Service("anotherService")
@Transactional("anotherTransactionManager")
public class AnotherDataSourceServiceImpl implements AnotherDataSourceService 
{

   //

}

Solution 2

here is my solution. base on spring-boot.1.2.5.RELEASE.

application.properties

first.datasource.driver-class-name=com.mysql.jdbc.Driver
first.datasource.url=jdbc:mysql://127.0.0.1:3306/test
first.datasource.username=
first.datasource.password=
first.datasource.validation-query=select 1

second.datasource.driver-class-name=com.mysql.jdbc.Driver
second.datasource.url=jdbc:mysql://127.0.0.1:3306/test2
second.datasource.username=
second.datasource.password=
second.datasource.validation-query=select 1

DataSourceConfig.java

@Configuration
public class DataSourceConfig {
    @Bean
    @Primary
    @ConfigurationProperties(prefix="first.datasource")
    public DataSource firstDataSource() {
        DataSource ds =  DataSourceBuilder.create().build();
        return ds;
    }

    @Bean
    @ConfigurationProperties(prefix="second.datasource")
    public DataSource secondDataSource() {
        DataSource ds =  DataSourceBuilder.create().build();
        return ds;
    }
}

Solution 3

I checked the source code you provided on GitHub. There were several mistakes / typos in the configuration.

In CustomerDbConfig / OrderDbConfig you should refer to customerEntityManager and packages should point at existing packages:

@Configuration
@EnableJpaRepositories(
    entityManagerFactoryRef = "customerEntityManager",
    transactionManagerRef = "customerTransactionManager",
    basePackages = {"com.mm.boot.multidb.repository.customer"})
public class CustomerDbConfig {

The packages to scan in customerEntityManager and orderEntityManager were both not pointing at proper package:

em.setPackagesToScan("com.mm.boot.multidb.model.customer");

Also the injection of proper EntityManagerFactory did not work. It should be:

@Bean(name = "customerTransactionManager")
public PlatformTransactionManager transactionManager(EntityManagerFactory customerEntityManager){

}

The above was causing the issue and the exception. While providing the name in a @Bean method you are sure you get proper EMF injected.

The last thing I have done was to disable to automatic configuration of JpaRepositories:

@EnableAutoConfiguration(exclude = JpaRepositoriesAutoConfiguration.class)

And with all fixes the application starts as you probably expect!

Solution 4

I have written a complete article at Spring Boot JPA Multiple Data Sources Example. In this article, we will learn how to configure multiple data sources and connect to multiple databases in a typical Spring Boot web application. We will use Spring Boot 2.0.5, JPA, Hibernate 5, Thymeleaf and H2 database to build a simple Spring Boot multiple data sources web application.

Solution 5

thanks to the answers of Steve Park and Rafal Borowiec I got my code working, however, I had one issue: the DriverManagerDataSource is a "simple" implementation and does NOT give you a ConnectionPool (check http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/datasource/DriverManagerDataSource.html).

Hence, I replaced the functions which returns the DataSource for the secondDB to.

public DataSource <secondaryDB>DataSource() {
    // use DataSourceBuilder and NOT DriverManagerDataSource 
    // as this would NOT give you ConnectionPool
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
    dataSourceBuilder.url(databaseUrl);
    dataSourceBuilder.username(username);
    dataSourceBuilder.password(password);
    dataSourceBuilder.driverClassName(driverClassName);
    return dataSourceBuilder.build();
}

Also, if do you not need the EntityManager as such, you can remove both the entityManager() and the @Bean annotation.

Plus, you may want to remove the basePackages annotation of your configuration class: maintaining it with the factoryBean.setPackagesToScan() call is sufficient.

Share:
116,412
tonym2105
Author by

tonym2105

Updated on August 21, 2020

Comments

  • tonym2105
    tonym2105 almost 4 years

    I'm trying to connect each @Repositories to different DataSource(s) with Spring Boot and Spring Data JPA. I used the following, http://xantorohara.blogspot.com/2013/11/spring-boot-jdbc-with-multiple.html, as a referrence. Here is the code I am using in an attempt to implement a similar solution using Spring Data JPA.

    CustomerDbConfig.java(First data source connection)

    @Configuration
    @EnableJpaRepositories(
            entityManagerFactoryRef = "orderEntityManager",
            transactionManagerRef = "orderTransactionManager",
            basePackages = {"com.mm.repository.customer"})
    public class CustomerDbConfig {
    
        @Bean(name = "customerEntityManager")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
            LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
            em.setDataSource(dataSource());
            em.setPackagesToScan(new String[] {"com.mm.domain.customer"});
    
            JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            em.setJpaVendorAdapter(vendorAdapter);
            em.setJpaProperties(additionalJpaProperties());
            em.setPersistenceUnitName("customerPersistence");
            em.setPackagesToScan("com.mm.domain.customer");
    
            return em;
        }
    
        Properties additionalJpaProperties(){
            Properties properties = new Properties();
            properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
            properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
            properties.setProperty("hibernate.show_sql", "true");
    
            return properties;
        }
    
        @Bean
        public DataSource dataSource(){
            return DataSourceBuilder.create()
                    .url("jdbc:h2:mem:customer:H2")
                    .driverClassName("org.h2.Driver")
                    .username("sa")
                    .password("")
                    .build();
        }   
    
        @Bean(name = "customerTransactionManager")
        public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(emf);
    
            return transactionManager;
        }
    }
    

    CustomerDbConfig.java (Second data source)

    @Configuration
    @EnableJpaRepositories(
            entityManagerFactoryRef = "orderEntityManager",
            transactionManagerRef = "orderTransactionManager",
            basePackages = {"com.mm.repository.customer"})
    public class CustomerDbConfig {
    
        @Bean(name = "customerEntityManager")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
            LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
            em.setDataSource(dataSource());
            em.setPackagesToScan(new String[] {"com.mm.domain.customer"});
    
            JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            em.setJpaVendorAdapter(vendorAdapter);
            em.setJpaProperties(additionalJpaProperties());
            em.setPersistenceUnitName("customerPersistence");
            em.setPackagesToScan("com.mm.domain.customer");
    
            return em;
        }
    
        Properties additionalJpaProperties(){
            Properties properties = new Properties();
            properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
            properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
            properties.setProperty("hibernate.show_sql", "true");
    
            return properties;
        }
    
        @Bean
        public DataSource dataSource(){
            return DataSourceBuilder.create()
                    .url("jdbc:h2:mem:customer:H2")
                    .driverClassName("org.h2.Driver")
                    .username("sa")
                    .password("")
                    .build();
        }   
    
        @Bean(name = "customerTransactionManager")
        public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(emf);
    
            return transactionManager;
        }
    }
    

    Customer.java (model)

    @Entity
    @Table(name = "customer")
    @Data
    @EqualsAndHashCode(exclude = {"id"})
    public class Customer {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer id;
    
        @Column(name = "name", nullable = false)
        private String name;
    
        @Column(name = "age", nullable = false)
        private Integer age;
    
    ....
    

    Order.java (model)

    @Entity
    @Table(name = "order")
    @Data
    @EqualsAndHashCode(exclude = {"id"})
    public class Order {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Integer id;
    
        @Column(name = "code", nullable = false)
        private Integer code;
    
        @Column(name = "quality", nullable = false)
        private Integer quality;
    

    ...

    CustomerRepository.java

    public interface CustomerRepository extends JpaRepository<Customer, Integer>{
    
    }
    

    OrderRepository.java

    public interface OrderRepository extends JpaRepository<Order, Integer> {
    
    }
    

    Finally, Application.java

    @Configuration
    @ComponentScan
    @EnableAutoConfiguration
    public class Application extends SpringApplication{
    
           public static void main(String[] args) {
                SpringApplication.run(Application.class, args);
            }
    
            @Bean
            public ServletRegistrationBean h2Console() {
                ServletRegistrationBean reg = new ServletRegistrationBean(new WebServlet(), "/console/*");
                reg.setLoadOnStartup(1);
                return reg;
            }
    }
    

    During start the following exceptions are thrown:

    -10-10 15:45:24.757 ERROR 1549 --- [           main] o.s.boot.SpringApplication               : Application startup failed
    
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customerTransactionManager' defined in class path resource [com/mm/boot/multidb/CustomerConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.persistence.EntityManagerFactory]: : No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:747)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:462)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1095)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:990)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
        at com.mm.boot.multidb.Application.main(Application.java:17)
    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:974)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:811)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:739)
        ... 18 common frames omitted
    
    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customerTransactionManager' defined in class path resource [com/mm/boot/multidb/CustomerConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.persistence.EntityManagerFactory]: : No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:747)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:462)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1095)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:990)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
        at com.mm.boot.multidb.Application.main(Application.java:17)
    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:974)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:811)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:739)
        ... 18 more
    

    Full code for the sample can be found on GitHub (https://github.com/tonym2105/samples/tree/master/boot-multidb-sample)

    Thank you in advance for the help.

  • tonym2105
    tonym2105 over 9 years
    First, thank you. I now get a "org.springframework.beans.factory.NoUniqueBeanDefinitionExc‌​eption: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: customerEntityManager,orderEntityManager" exception. GitHib updated with suggested changes.
  • Rafal Borowiec
    Rafal Borowiec over 9 years
    EntityManagerInViewInterceptor auto configuration is causing that. You should be able to disable it easily by providing spring.jpa.open_in_view = false in application properties.
  • tonym2105
    tonym2105 over 9 years
    That works. But what is the implication of disabling the property? Thanks again for the help.
  • Rafal Borowiec
    Rafal Borowiec over 9 years
    "Spring web request interceptor that binds a JPA EntityManager to the thread for the entire processing of the request. Intended for the "Open EntityManager in View" pattern, i.e. to allow for lazy loading in web views despite the original transactions already being completed."
  • tonym2105
    tonym2105 over 9 years
    Both entities are created in a single database. I noticed this in both H2 and MySQL. Any help is greatly appreciated.
  • IllSc
    IllSc about 9 years
    How do I tell/configure the Spring so this entitiy/repository belong to this database?
  • Admin
    Admin about 8 years
    datasource.xxx.url = datasource.xxx.username = datasource.xxx.password = datasource.xxx.driver-class-name = com.mysql.jdbc.Driver
  • Alex Pineda
    Alex Pineda over 7 years
    How do you reference this? I've gotten this far however I don't know how to "summon" the second data source via JPA. I figured it would be either in the entity annotation or Query parameter or something.
  • david
    david over 7 years
    like this. @Autowired @Qualifier("firstDataSource") private DataSource firstDataSource; @Autowired @Qualifier("secondDataSource") private DataSource secondDataSource;
  • Mike3355
    Mike3355 over 7 years
    Sorry that was a typo on my part. I had to rename a few things and I missed that one. That is not the issue but thank you for your efforts.
  • Brian
    Brian about 7 years
    This saved me! Wanted to add that when followed verbatim, this works on 1.5.2.RELEASE with success.
  • Purushothaman
    Purushothaman about 6 years
    I was able to make transactions to two different datasource without using @Transactional annotation in any of the implementation classes. Is this behavior an expected one? Using Spring-Boot 1.5.6.RELEASE
  • Steve Park
    Steve Park about 6 years
    I believe spring manage transaction via AOP autoproxying with @ Transactional annotation. I have seen some spring technology like @ RepositoryRestResource in Spring Data Rest works without the @ Transactional automagically. That I guess some amount of code and layer are maybe generated during compile time with default transaction setup. However I wonder how to assign different transactionManager to the services or repositories which need to use different type database without specifying it
  • GarouDan
    GarouDan about 6 years
    How can you create or summon the second entity manager using this? I'm having a bad time to do it
  • S34N
    S34N about 5 years
    Anyone managed to get this to work? To link the custom datasources with JPA, or people are just assuming things without real examples?
  • S34N
    S34N about 5 years
    I've noticed that this solution only works when both databases are mapped to the same JDBC Driver. However, won't work when you've two different data sources connecting to two different Drivers. EG: one Driver using MariaDB Driver, & the other one using the ibm DB2Driver...