Multiple databases with Spring Boot and Spring Data JPA

A little while back I knocked up a post describing how to enable a Spring application to connect to multiple data sources. At the time, I had only just heard about Spring Boot at the SpringOne 2GX conference in Santa Clara, so the examples didn’t take advantage of that and also didn’t work around some of the autowiring that it does.

Recently, I was working on a little ETL project to migrate data from one database to another with a different structure, so I returned to this problem and the following is the result.

First, if you want to get hold of a working (including some simple tests) example project, here it is:

https://github.com/gratiartis/multids-demo/tree/now-with-spring-boot

As previously, when you define an entity manager, you can define where it should scan for entities and repository classes. The classes can be named individually, but it is easiest if you put your domain entities and repository classes into their own packages and point the entity manager factory at the package. In this example, I used:

  • com.sctrcd.multids.foo.domain
  • com.sctrcd.multids.foo.repo
  • com.sctrcd.multids.bar.domain
  • com.sctrcd.multids.bar.repo

I suspect that it’s certainly possible to get around it, but I found that due to Spring Boot trying to inject beans based on default names, it was easiest to set up one of the data sources to use the defaults and the other to use bean names that I defined. As you can see in the application.yml below:

… the spring.datasource.url, spring.datasource.username and spring.datasource.password properties are all defined for the ‘default’ datasource. I define some additional non-conventional properties for the additional schema. We will see how those are picked up shortly.

Beyond the application.yml configuration, all we need to do is define @Configuration beans which will pick up the properties. First, a @Configuration to wire up the ‘default’ data source. This defines each bean as @Primary, to ensure that they are the beans picked up by anything which does not specify a @Qualifier:

Second a @Configuration to wire up the additional datasource. It is essentially identical to the ‘default’ configuration, except that it defines non-conventional names for the data source, entity manager factory and transaction manager and scans different packages for the entities and repositories. It also defines the named transaction manager in the @EnableJpaRepositories annotation and does not define the beans as @Primary.

Beyond those configuration classes, everything is just the standard setup for a Spring Boot / Spring Data JPA application, so if you have an application connecting to a single database already, there isn’t a lot of modification to support connecting to additional databases.

51 thoughts on “Multiple databases with Spring Boot and Spring Data JPA

  1. Hi, I’m have a similar problem. Over stackoverflow i found your blog post. One thing, you write that in the second config should not define as primary, but you do it in the example.

    I implemented your solution but it didn’t work, my JpaRepo (Interface) has the wrong entityManager (from the base, but i need the second). Have you andy idea how could it be resolved? If you like i can add the link to stackoverflow.

    Thank’s in advance.

    Like

    1. Thanks for pointing that out. When I created the Gist, I copied the default config instead of basing it on my working code. Doh! I had removed the @Primary annotation from the datasource, but not the other beans. It’s fixed now. 🙂

      If you have the code available somewhere public I’d be happy to take a look. There may be something I should add to the blog post, which I missed.

      Like

  2. Hi, very interesting post! Exactly what I’m looking for. I have referred your working example here https://github.com/gratiartis/multids-demo/tree/now-with-spring-boot and tried the same. but I’m facing the below exception always! Do you have any clue on this?

    2016-02-11 16:50:02.773 INFO 5156 — [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
    name: external
    …]
    2016-02-11 16:50:02.907 INFO 5156 — [ main] org.hibernate.Version : HHH000412: Hibernate Core {4.3.11.Final}
    2016-02-11 16:50:02.911 INFO 5156 — [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
    2016-02-11 16:50:02.914 INFO 5156 — [ main] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
    2016-02-11 16:50:03.257 INFO 5156 — [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
    2016-02-11 16:50:03.464 WARN 5156 — [ main] o.a.tomcat.jdbc.pool.PooledConnection : Not loading a JDBC driver as driverClassName property is null.
    2016-02-11 16:50:03.498 ERROR 5156 — [ main] o.a.tomcat.jdbc.pool.ConnectionPool : Unable to create initial connections of pool.

    java.sql.SQLException: The url cannot be null
    at java.sql.DriverManager.getConnection(DriverManager.java:649) ~[na:1.8.0_60]
    at java.sql.DriverManager.getConnection(DriverManager.java:208) ~[na:1.8.0_60]
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:305) ~[tomcat-jdbc-8.0.30.jar:na]
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:200) ~[tomcat-jdbc-8.0.30.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:708) [tomcat-jdbc-8.0.30.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:642) [tomcat-jdbc-8.0.30.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:464) [tomcat-jdbc-8.0.30.jar:na]
    at org.apache.tomcat.jdbc.pool.ConnectionPool.(ConnectionPool.java:141) [tomcat-jdbc-8.0.30.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:115) [tomcat-jdbc-8.0.30.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:102) [tomcat-jdbc-8.0.30.jar:na]
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:126) [tomcat-jdbc-8.0.30.jar:na]
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:139) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcServicesImpl.java:279) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:124) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) [spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFa
    ctoryBean.java:343) [spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) [spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1054) [spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]

    Like

  3. How are you running it? It looks like the application.yml in the config directory might not have been loaded, as that provides things like the URL for the database.

    Note that there is a SQL script in the ‘db’ directory, which creates the two schemas that the application will try to connect to. Assuming that you are testing with MySQL, then that script should work, and a few tweaks to the application.yml (change URL, passwords, etc for your local config) should let you connect to it.

    Like

    1. Nice work. Hopefully it was easy enough! btw – In case you hadn’t seen them, you can set properties such as spring.datasource.min-idle, spring.datasource.max-idle and spring.datasource.max-active to control how many connections there are in each pool.

      Like

  4. Thanks, I need this to setup 4 database connections = 4 datasources. There are pieces here I need to incorporate to make it work. Appreciate the details!

    Like

  5. Seems to be exactly what I need. But where does EntityManagerFactoryBuilder come from? When I try to launch the code, I get the exception:
    “Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}”

    Should I define the bean myself of somehow ask Spring to do it for me?

    Like

    1. Spring should be injecting that for you, but that message indicates that the application isn’t being wired up correctly. Maybe your database config has an error, which means that Spring is unable to create the beans relating to it?

      Also, are you running as a Spring Boot application? If not, then as xtreye mentions below, you may need to do some of the additional configuration described in my previous post: https://scattercode.co.uk/2013/11/18/spring-data-multiple-databases/

      Like

  6. Seem to be exactly what I need, but could you please tell where does EntityManagerFactoryBuilder come from?
    I am asking because I getting message “No qualifying bean of type [org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder] found for dependency” when try to use this solution. I do not use @SpringBootApplication because this not the app but one of the modules.

    Like

    1. Above, both datasources defined in application.yml are using the MySQL driver. Just put the Oracle drivers on the classpath and change one of the datasources to use them. You shouldn’t need to change anything anywhere else.

      Like

  7. Hi,
    I did the same configuration as you did. But getting the following exception.
    Could you please provide your inputs.

    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: barEntityManagerFactory,entityManagerFactory
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:572)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:531)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:697)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:670)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:354)

    Like

  8. org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘genericDaoImpl’: Injection of persistence dependencies failed; 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: barEntityManagerFactory,entityManagerFactory
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:357)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)

    Like

    1. Unfortunately not. This works by using Spring’s @EnableJpaRepositories annotation to define the package which should be scanned to find repositories for each data source and inject entity and transaction managers. So anything in the same package will use the same data source.

      Like

  9. Hi, I’m implementing your example and I’m able to start my spring boot application without errors but at runtime I have this error:

    ERROR: Bean named ‘entityManagerFactory’ must be of type [org.springframework.transaction.PlatformTransactionManager], but was actually of type [com.sun.proxy.$Proxy81]

    It seems that I applied all your indications, what’s wrong?

    Thanks

    Like

    1. It’s hard to say. That error usually means that for some reason Spring is unable to use CGLIB. Going by a quick look at StackOverflow, sometimes also, a third party tool, such as Cobertura could be manipulating your bytecode to replace references to concrete classes with proxies.

      Like

  10. FYI, to use non-default values for the naming strategy etc I had to do the following (the property values don’t need to be hard-coded, obviously). There may be a better way to do this….

    @Bean(name = “barEntityManagerFactory”)
    public LocalContainerEntityManagerFactoryBean barEntityManagerFactory(
    EntityManagerFactoryBuilder builder,
    @Qualifier(“barDataSource”) DataSource barDataSource) {

    HashMap properties = new HashMap();
    properties.put(“hibernate.hbm2ddl.auto”, “update”);
    properties.put(“hibernate.dialect”, “org.hibernate.dialect.PostgreSQL9Dialect”);
    properties.put(“hibernate.ejb.naming_strategy”, “org.hibernate.cfg.EJB3NamingStrategy”);

    return builder
    .dataSource(barDataSource)
    .packages(“com.sctrcd.multidsdemo.bar.domain”)
    .persistenceUnit(“bar”)
    .properties(properties)
    .build();
    }

    Like

  11. Thanks for the great sample. It seems like it breaks chacheManager autoconfig. Any idea how to fix this?

    pringframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘cacheManager’ is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:702)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1180)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174)
    at com.wiser.WpmApplication.main(WpmApplication.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)

    Like

  12. Hey , Why does spring boot throw this expection –> “Caused by: java.lang.IllegalArgumentException: Repository interface must not be null on initialization!

    Like

  13. Hi sctrcdr,
    I have implemented Multi data-source using spring boot. I have a requirement to 20 data sources. Is there any way i can implement dynamically with out include all the data sources in below config class?

    Please advice, much appreciated. Thanks

    DataSourceConfig.java

    @Bean(name = “ds-aus”)
    @Primary
    @ConfigurationProperties(prefix=”spring.datasource”)
    public DataSource dataSourceAUS() {
    return DataSourceBuilder.create().build();
    }

    @Bean(name = “ds-ind”)
    @ConfigurationProperties(prefix=”spring.datasource.cl”)
    public DataSource dataSourceIND() {
    return DataSourceBuilder.create().build();
    }
    • Reply•Share ›

    Like

    1. hi narendra,
      Could you please share me examples :
      Based on user request the different mysql DataBases connection using Spring boot JPA using Spring liquibase and HikariDataSource (Two mysql DataBases)

      Like

  14. Great article. This addresses exactly what I’m having trouble with right now, however I’m still getting “Not a managed type” exception for one of my entities. Interestingly enough, the entity that gets this exception is the one that does not have the LocalContainerEntityManagerFactoryBean named “entityManagerFactory” (I’ve named the other config’s bean “entityManagerFactory” and the other entity became the unmanaged type). All the properties in both config’s @EnableJpaProperties are set correctly. I’ve also tried to specify bean names as you outlined in your other article, in which case I receive the “No bean named ‘entityManagerFactory’ is defined” error.

    Other info: I’m using spring boot. One datasource is MySQL and the other is Vertica. If I isolate either datasource in my project everything works as expected.

    Have you ever run in to this or have any idea why this might be happening? Thanks in advance.

    Like

    1. Do you have your repositories and entities in separate packages, so that you can ensure that classpath scanning doesn’t pick up the wrong ones?

      And the correct path to the domain entities in the LocalContainerEntityManagerFactoryBean definitions?

      Like

      1. Thanks for your very prompt response. I figured out the issue – I had too many annotations in my main method. Specifically, I had @SpringBootApplication while also having @ComponentScan and @EntityScan… I removed everything but @SpringBootApplication and everything finally worked!

        Like

  15. Great article. This addresses exactly what I’m having trouble with right now, however I’m still getting “Not a managed type” exception for one of my entities. Interestingly enough, the entity that gets this exception is the one that does not have the LocalContainerEntityManagerFactoryBean named “entityManagerFactory” (I’ve named the other config’s bean “entityManagerFactory” and the other entity became the unmanaged type). All the properties in both config’s @EnableJpaProperties are set correctly. I’ve also tried to specify bean names as you outlined in your other article, in which case I receive the “No bean named ‘entityManagerFactory’ is defined” error.

    Other info: I’m using spring boot. One datasource is MySQL and the other is Vertica. If I isolate either datasource in my project everything works as expected.

    Have you ever run in to this or have any idea why this might be happening? Thanks in advance.

    Like

  16. We have struggled for days to get two data sources to work in a Spring Boot application. This approach seems like the most sane, but we still cannot make it work. As far as I can see we have followed the pattern exactly, but the application fails to create the second repository with this error:

    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘lookupRestController’ defined in file [/home/nils/workspace/RAÄ/platsr-sb/platsrapi/build/classes/main/se/raa/platsr/controller/LookupRestController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘lookupService’ defined in file [/home/nils/workspace/RAÄ/platsr-sb/platsrapi/build/classes/main/se/raa/platsr/service/LookupService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘LMPlaceRepository’: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class se.raa.platsr.model.lookup.LMPlace

    I thought the .packages(…) call here should take care of that:

    @Bean(name = “lookupEntityManagerFactory”)
    public LocalContainerEntityManagerFactoryBean lookupEntityManager(final EntityManagerFactoryBuilder builder,
    @Qualifier(“lookupDataSource”) final DataSource dataSource) {
    return builder.dataSource(dataSource).packages(“se.raa.platsr.model.lookup”).persistenceUnit(“lookup”).build();
    }

    So, what is it that I don’t understand/have missed out?

    Like

  17. We have spent two days getting two data sources to work in a Spring Boot application. This approach is the sanest we have found, but we still cannot get it to work. We get this for an Entity class to be managed by the secondary data source/entity manager:

    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘lookupRestController’ defined in file [/home/nils/workspace/RAÄ/platsr-sb/platsrapi/build/classes/main/se/raa/platsr/controller/LookupRestController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘lookupService’ defined in file [/home/nils/workspace/RAÄ/platsr-sb/platsrapi/build/classes/main/se/raa/platsr/service/LookupService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘LMPlaceRepository’: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class se.raa.platsr.model.lookup.LMPlace

    I thought this would be adressed by the call to .packages(…) in the EntityManagerFactory builder:

    @Bean(name = “lookupEntityManagerFactory”)
    public LocalContainerEntityManagerFactoryBean entityManager(final EntityManagerFactoryBuilder builder,
    @Qualifier(“lookupDataSource”) DataSource dataSource) {
    return builder.dataSource(dataSource).packages(LMPlace.class).persistenceUnit(“lookup”).build();
    }

    I have tried with a package name as well

    @Bean(name = “lookupEntityManagerFactory”)
    public LocalContainerEntityManagerFactoryBean entityManager(final EntityManagerFactoryBuilder builder,
    @Qualifier(“lookupDataSource”) DataSource dataSource) {
    return builder.dataSource(dataSource).packages(“se.raa.platsr.model.lookup”).persistenceUnit(“lookup”).build();
    }

    with no success. So, what can it be that I don’t understand, or have configured wrong? The error comes from the initialization of a class that should use this configuration:

    @Service
    @Transactional(“lookupTransactionManager”)
    public class LookupService {

    Is this where we are going wrong?

    Like

    1. It looks like the problem is with detecting se.raa.platsr.model.lookup.LMPlace as an @Entity. As in my example, I’d change that LCEMFB implementation to be an EntityManagerFactory and use setPackagesToScan to point at se.raa.platsr.model.lookup. It’s generally better to return an interface rather than an implementation.

      Like

  18. Great! Thanks for sharing.

    I have a question. My project structure is like this:

    com.app.controller
    com.app.service

    com.app.domain
    com.app.domain.Foo1
    com.app.domain.Foo2
    com.app.domain.Foo3
    com.app.domain.Bar1
    com.app.domain.Bar2
    com.app.domain.Bar3

    com.app.repository
    com.app.repository.Foo1Repository
    com.app.repository.Foo3Repository
    com.app.repository.Foo2Repository
    com.app.repository.Bar1Repository
    com.app.repository.Bar2Repository
    com.app.repository.Bar3Repository

    as you suggest it should be structured like this?:

    com.app.controller
    com.app.service

    com.app.Foo1.domain
    com.app.Foo1.repository
    com.app.Foo2.domain
    com.app.Foo2.repository
    com.app.Foo3.domain
    com.app.Foo3.repository
    com.app.Bar1.domain
    com.app.Bar1.repository
    com.app.Bar2.domain
    com.app.Bar2.repositroy
    com.app.Bar3.domain
    com.app.Bar3.repository

    And if i have 50 classes to deal with databases i need 50 packeges each (an additionaly 2: domain and repo)?

    Ani idea how to do it right?

    Thanks

    Like

    1. You don’t need a separate package for each entity. Just a separate package for each database. So more like:

      com.app.foo.domain.Foo1
      com.app.foo.repository.Foo1Repository
      com.app.bar.domain.Bar1
      etc…

      Like

  19. bar:
    datasource:
    url: jdbc:mysql://localhost/bar_schema
    username: root
    password: d4t4b4s3sForLif3
    driverClassName: com.mysql.jdbc.Driver
    test-on-borrow: true \\ in spring boot 1.5.3 it seems this is moved under tomcat.
    test-while-idle: true \\ but when I tried something like below it is not working can anyone please help?
    validation-query: select 1;\\

    bar:
    datasource:
    url: jdbc:mysql://localhost/bar_schema
    username: root
    password: d4t4b4s3sForLif3
    driverClassName: com.mysql.jdbc.Driver
    tomcat:
    test-on-borrow: true
    test-while-idle: true
    validation-query: select 1;

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s