I'm trying to implement multiple Spring Data Modules on one project and select what type of Data Module to use (JPA or JDBC) on runtime.
After several attempts, I reach this implementation:
@Configuration
@Profile("jpa")
@EnableJpaRepositories(basePackages = "com.example.repository.jpa")
public class JpaConfiguration {
@Autowired
public ExampleInterface example;
@Bean
public ExampleInterface example(){
return this.example;
}
}
@Configuration
@Profile("jdbc")
@EnableJdbcRepositories(basePackages = "com.example.repository.jdbc")
public class JdbcConfiguration {
@Autowired
public ExampleInterface example;
@Bean
public ExampleInterface example(){
return this.example;
}
}
@NoRepositoryBean
public interface ExampleInterface extends CrudRepository<Example,String> {
}
package com.example.repository.jdbc;
@Repository
public interface ExampleJdbcInterface extends ExampleInterface, CrudRepository<Example, String> {
}
package com.example.repository.jpa;
@Repository
public interface ExampleJpaInterface extends ExampleInterface, JpaRepository<Example, String> {
}
@RestController
public class ExampleController {
@Autowired
private ExampleInterface repo;
public ExampleController(){
}
}
And on my application.properties I have spring.profiles.active=jdbc
But then when I run the app the log show
The following profiles are active: jdbc
This is what it's suppose to do, so it's okay, but also:
Multiple Spring Data modules found, entering strict repository configuration mode!
And then the Spring try to lookup the entitys for both Jdbc and Jpa and assume JPA as the default. What can I do?
So many time wasted on this and it was just so easy.. Configure your application.properties with
spring.data.jpa.repositories.enabled=false
spring.data.jdbc.repositories.enabled=true
Done! Now it will return a JPA or a JDBC instance. You don't even need to have separate interfaces extending a common interface, just make one extending CrudRepository and you are all set.
EDIT: Another approach
Not using that flags on application.properties and only use spring.profiles.active=jdbc (for example) Delete my configuration classes and put @Profile for each interface (like my example, ExampleJdbcInterface will have @Profile("jdbc") and ExampleJpaInterface will have @Profile("jpa"). Now add the enablerepositories to the main class, meaning it will be like:
@SpringBootApplication
@EnableJdbcRepositories(basePackages="com.example.repository.repository.jdbc")
@EnableJpaRepositories(basePackages="com.example.repository.repository.jpa")
public class ExampleApplication {
Now the Spring will only lookup for the interfaces with the right profile (most probably my example didn't work because I had the profile in the configuration only, so he was trying anyways to lookup for all the repositories, doing this will solve the problem because he will only "lookup" for only one instance only. Also, the enablerepositories is needed because otherwise he will try to default to JPA, even if only the interfaces of package jdbc are activated with the @Profile)
This solution have an advantage: suppose we want to add one method for our repositories. In this way, we can create a custom interface and corresponding implementation on each technology, and then each interface will extend that custom implementation of that method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.