Reputation: 21
I'm currently working on Spring Boot project where I need to connect to more than 2 data source (actually 4). I found many examples how to connect to 2 DS and it works, but when I add next in the same way it's not working:
...Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class...
Is there any restriction on data sources? Or is it possible to connect to more than 2 DS?
Upvotes: 1
Views: 1099
Reputation: 21
Thanks for your help. Actually I did all configuration right but ... (one small misspell crash all :)) As I was starting including my code I found it, fixed and now all works fine. But here is my code as example (maybe someone will use it :))
All three entities and repositories (Shadow, Main, Project) are configured exactly in the same way so I put it only once. (the only differences is that DS for Main is as @Primary.
Thanks. BR
application.properties
#-------------------------- first
spring.datasource.url=jdbc:mysql://
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#-------------------------- second
second.datasource.url=jdbc:mysql://
second.datasource.username=
second.datasource.password=
second.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#-------------------------- third
third.datasource.url=jdbc:mysql://
third.datasource.password=
third.datasource.username=
third.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Shadow.java
package com.server.shadow.domain;
import ...
@Entity
@Table(name = "shadow")
public class Shadow {
@Id
private String id;
private String shadow;
public Shadow(){}
//getters and setters
}
ShadowRepository.java
package com.server.shadow.repo;
import ...
@Repository
public interface ShadowRepository extends JpaRepository<Shadow,Long> {
}
ShadowDbConf.java
package com.server;
import ...
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "shadowEntityManagerFactory",
transactionManagerRef = "shadowTransactionManager",
basePackages = {"com.server.shadow.repo"}
)
public class ShadowDbConf {
@Bean(name = "shadowDataSource")
@ConfigurationProperties(prefix = "second.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "shadowEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean
shadowEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("shadowDataSource") DataSource dataSource
) {
return
builder
.dataSource(dataSource)
.packages("com.server.shadow.domain")
.persistenceUnit("shadow")
.build();
}
@Bean(name = "shadowTransactionManager")
public PlatformTransactionManager shadowTransactionManager(
@Qualifier("shadowEntityManagerFactory") EntityManagerFactory
shadowEntityManagerFactory
) {
return new JpaTransactionManager(shadowEntityManagerFactory);
}
}
MainController.java
package com.server;
import ...
@RestController
public class MainController {
private final ShadowRepository shadowRepository;
private final MainRepository mainRepository;
private final PojectRepository projectRepository;
@Autowired
MainController(ShadowRepository shadowRepository, MainRepository mainRepository,PojectRepository projectRepository) {
this.shadowRepository = shadowRepository;
this.mainRepository = mainRepository;
this.projectRepository = projectRepository;
}
@GetMapping(path = "/shadow")
public @ResponseBody Iterable<Shadow> getShadows(){
return shadowRepository.findAll();
}
}
Upvotes: 0
Reputation: 192
Adding to what @Surya said
Step 1: Set up the data base configuration in application.properties file as mentioned above.
Step 2:You need to create a bean.In your case u need to create 2 separate bean pointing to 2 diff data source.
@Bean("firstds")
@ConfigurationProperties(prefix="spring.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean("secondds")
@ConfigurationProperties(prefix="spring.secondDatasource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
U can create this 2 bean in a single class.
Now wondering how to use this bean!
@Autowired
@Qualifier("firstds")
NamedParameterJdbcTemplate firstConnection;
result = firstConnection.query(Your query goes here)
Above query will always hit first db via the bean you created. Similarly you can use connection to hit db 2 via the second bean.
Upvotes: 0
Reputation: 2749
Create as many datasource you want. No restrictions i am aware of. It is just another bean .Refer here
#first db
spring.datasource.url = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
spring.datasource.driverClassName = oracle.jdbc.OracleDriver
#second db ...
spring.secondDatasource.url = [url]
spring.secondDatasource.username = [username]
spring.secondDatasource.password = [password]
spring.secondDatasource.driverClassName = oracle.jdbc.OracleDriver
@Bean("firstds")
@ConfigurationProperties(prefix="spring.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean("secondds")
@ConfigurationProperties(prefix="spring.secondDatasource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
Upvotes: 3