【问题标题】:Getting a specific instance of EntityManager incase of multiple datasources in Micronaut在 Micronaut 中获取多个数据源的 EntityManager 的特定实例
【发布时间】:2021-03-11 16:12:05
【问题描述】:

我对 Micronaut 应用程序的 application.yml 中的两个不同数据源有以下定义 -

datasources:
  default:
    url: <jdbc-url>
    driverClassName: org.postgresql.Driver
    username: <username>
    password: <password>
    dialect: POSTGRES
    schema: <schema>
  ms-sql:
    url: <jdbc-url>
    driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
    username: <username>
    password: <password>
    dialect: org.hibernate.dialect.SQLServer2012Dialect
    schema: <schema>

如何在下面的 Service 类中注入特定的 EntityMananger 实例?

服务类片段:

@Inject
private EntityManager em;

@Transactional
@Override
public int callSP(int num) {
    StoredProcedureQuery query = em.createStoredProcedureQuery("storelist.testSP1")
                                    .registerStoredProcedureParameter("InputInt", Integer.class, ParameterMode.IN)
                                    .registerStoredProcedureParameter("OutputInt", Integer.class, ParameterMode.OUT)
                                    .setParameter("InputInt", num);
    query.execute();
    Integer result = (Integer) query.getOutputParameterValue("OutputInt");
    
    return result;
}

【问题讨论】:

    标签: java jpa datasource micronaut micronaut-data


    【解决方案1】:

    对于每个DataSource 配置(也注入到由ConfigurationProperties 驱动的bean DataSourceConfiguration),Micronaut 将创建一个合格的SessionFactory bean。

    在下面,每个合格的SessionFactory 将导致一个TransactionManager 合格的bean 创建。

    根据io.micronaut.context.annotation.EachBean 注入机制,创建的每个 bean 将在驱动其创建的 bean 限定名称之后为 @Named

    从配置到创建 bean 的短注入路径如下:

    datasources.some-datasource-name (configuration item within your .yaml, .properties...)
                  |
                  |
                  v
        DataSourceConfiguration @Named("some-datasource-name")
                  |
                  |
                  v
             DataSource @Named("some-datasource-name")
                  |
                  |
                  v
            SessionFactory @Named("some-datasource-name")
                  |
                  |
                  v
          TransactionManager @Named("some-datasource-name")
                  |
                  |
                  v
         RepositoryOperations @Named("some-datasource-name")
    

    然后,您将不得不以编程方式使用合格的 TransactionManager 以及 事务感知 EntityManager 来执行 JPA 操作(注意 @Transactional程序化事务样式中不再需要注释):

    @Singleton
    public class MyServiceImpl implements MyService {
    
        private EntityManager em; // transaction-aware bean
    
        private final SynchronousTransactionManager<Connection> transactionManager;
    
        public MyServiceImpl(@NonNull EntityManager entityManager, @NonNull @Named("ms-sql") SynchronousTransactionManager<Connection> transactionManager) {
            this.em = entityManager;
            this.transactionManager = transactionManager;
        }
    
        @Override
        public int callSP(int num) {
            return transactionManager.executeRead(status -> {
                StoredProcedureQuery query = em.createStoredProcedureQuery("storelist.testSP1")
                        .registerStoredProcedureParameter("InputInt", Integer.class, ParameterMode.IN)
                        .registerStoredProcedureParameter("OutputInt", Integer.class, ParameterMode.OUT)
                        .setParameter("InputInt", num);
                query.execute();    
                return (Integer) query.getOutputParameterValue("OutputInt");
            });
        }
    }
    

    或者注入一个合格的RepositoryOperations,在你的情况下这将是HibernateJpaOperations的一个实例,并用它来查询你的数据源。

    【讨论】:

      猜你喜欢
      • 2020-10-29
      • 2014-11-27
      • 1970-01-01
      • 1970-01-01
      • 2019-09-19
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      相关资源
      最近更新 更多