micronaut-data : multiple data sources

落花浮王杯 提交于 2021-02-11 15:30:15

问题


I have multiple databases in yml, how to get country specific repository? i am getting country name at runtime and based on country name i need to do operation with that country database, with single database it taking default database repository from yml.

as per micronaut document : In multiple datasource scenario, the @io.micronaut.data.annotation.Repository annotation can be used to specify the datsource configuration to use. By default Micronaut Data will look for the default datasource.

my query remains same for all database, only db instance get selected at runtime for operations.

https://micronaut-projects.github.io/micronaut-data/snapshot/guide/index.html

Error:

Caused by: io.micronaut.context.exceptions.NonUniqueBeanException: Multiple possible bean candidates found: [io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations, io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations, io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations]

yml

datasources:
  india-db:
    validationQuery: SELECT 1 FROM DUAL
    driverClass: oracle.jdbc.driver.OracleDriver
    url: url-1
    autoCommit: true
    username: username
    password: password
  australia-db:
    validationQuery: SELECT 1 FROM DUAL
    driverClass: oracle.jdbc.driver.OracleDriver
    url: url-2
    autoCommit: true
    username: password
    password: password
  japan-db:
    validationQuery: SELECT 1 FROM DUAL
    driverClass: oracle.jdbc.driver.OracleDriver
    url: url-3
    autoCommit: true
    username: username
    password: password

Repository

//@Repository(value = "india-db")
@JdbcRepository(dialect = Dialect.ORACLE)
public class AppRepository {

    private final JdbcOperations jdbcOperations;

    @Inject
    public AppRepository(JdbcOperations jdbcOperations) {
        this.jdbcOperations = jdbcOperations;
    }
    
    @Transactional
    public String operation(){
    }
}

Service

@Singleton
public class AppService {
   
    AppRepository appRepository;
   
    @Inject
    public AppService(AppRepository appRepository){
      this.appRepository=appRepository;
    }
    
    public void method(String country){
    if(country.equals("india"){  
       //do india operation with india-db
       appRepository.operation();
    }else if(australia){
      //do australia operation with australia -db
        appRepository.operation();
     }else if(japan){
      //do japan operation with japan-db
       appRepository.operation();
     }
     else{
     throw exception();
     }
    }
}   

回答1:


I can't be sure if this helps you, but one way I could think of based on what you have said -

  1. You already have 3 different datasources configured, for 3 countries you have.

  2. You perhaps can define 3 separate Repository classes. Each marked as @Repository("india-db") etc

  3. Along with @Transactional also mark your method with @TransactionAdvice("india-db")

  4. And now code would be

    if(country.equals("india"){  
       indiaAppRepository.operation();
    

    }

  5. If the code is same across all regions, and no conflicts across regional setup, it could be possible to move the operation to a parent class or interface default method.

There possibly are more ways to do this. But this is how I got it working with 2 different datasources. I am using Micronaut 2.0 and micronaut-data 1.0.2 @TransactionAdvice also seems to work only on methods. When I tried adding it on the class, it didnt work. The interceptor seems to be looking for it, only on the method.



来源:https://stackoverflow.com/questions/62797107/micronaut-data-multiple-data-sources

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!