【问题标题】:setting DataSource programmatically in Micronaut + Hibernate for Heroku Postgres在 Micronaut + Hibernate 中为 Heroku Postgres 以编程方式设置 DataSource
【发布时间】:2020-01-22 23:24:43
【问题描述】:

我有一个要部署在 Heroku 上的应用程序。 Heroku 会不时更新数据库凭据,它们会自动将连接配置注入一个环境变量。这个环境变量可以解析得到用户、密码和URL。

我尝试按照他们推荐的方式进行 DataSource 配置。

@Factory
//@Requires(env = Environment.HEROKU)
public class HerokuDataSourceConfig {

    @Bean
    public DataSource dataSource() throws URISyntaxException {
//        URI dbUri = new URI(System.getenv("DATABASE_URL"));

//        String username = dbUri.getUserInfo().split(":")[0];
//        String password = dbUri.getUserInfo().split(":")[1];
//        String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath() + "?sslmode=require";

        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:postgresql://localhost:5432/postgres");
        config.setUsername("postgres");
        config.setPassword("");
        config.setDriverClassName("org.postgresql.Driver");
        config.setConnectionTestQuery("SELECT 1");

        return new HikariUrlDataSource(config);
    }
}

注释的行来自初始的heroku配置,未注释的代码仅用于本地测试。

当我尝试运行应用程序并点击需要 Hibernate 的端点时,我得到了这个

No bean of type [javax.persistence.EntityManager] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).

我按照建议激活了跟踪,这里是一些相关的日志数据

20:24:50.414 [pool-1-thread-15] DEBUG i.m.context.condition.Condition - Bean [Definition: io.micronaut.configuration.hibernate.jpa.EntityManagerFactoryBean] will not be loaded due to failing conditions:
20:24:50.414 [pool-1-thread-15] DEBUG i.m.context.condition.Condition - * No bean of type [interface org.hibernate.boot.SessionFactoryBuilder] present within context
20:28:04.598 [main] DEBUG i.m.context.condition.Condition - Bean [Definition: io.micronaut.jdbc.spring.DataSourceTransactionManagerFactory] will not be loaded due to failing conditions:
20:28:04.599 [main] DEBUG i.m.context.condition.Condition - * Custom condition [class io.micronaut.jdbc.spring.HibernatePresenceCondition] failed evaluation
20:28:04.895 [main] DEBUG i.m.context.condition.Condition - Bean [Definition: io.micronaut.configuration.hibernate.jpa.EntityManagerFactoryBean] will not be loaded due to failing conditions:
20:28:04.895 [main] DEBUG i.m.context.condition.Condition - * No bean of type [class org.hibernate.boot.MetadataSources] present within context
20:28:04.895 [main] DEBUG i.m.context.condition.Condition - Bean [Definition: io.micronaut.configuration.hibernate.jpa.EntityManagerFactoryBean] will not be loaded due to failing conditions:
20:28:04.896 [main] DEBUG i.m.context.condition.Condition - * No bean of type [interface org.hibernate.boot.SessionFactoryBuilder] present within context

我做错了什么?可能配置很好,但不知何故 Micronaut 不知道我新配置的数据源。

当我调试这段代码时,当 micronaut 启动时,它会在某个时候进入工厂并创建数据源。之前的日志是在调用数据源工厂之前打印出来的。

【问题讨论】:

    标签: spring hibernate heroku heroku-postgres micronaut


    【解决方案1】:

    仅仅使用@Bean,它就是一个重复创建的原型bean。尝试使用:

    @Singleton
    @Primary
    public DataSource dataSource()
    ...
    

    【讨论】:

    • 有机会我会试试这个。与此同时,我找到了另一种 Heroku 部署解决方案,我将添加到答案中。
    【解决方案2】:

    与此同时,我在 Heroku 的帮助下找到了解决方案。

    对于像我这样使用 gradle buildpack 的应用程序,Heroku 会向容器中注入以下环境变量。一开始我没看到,我只知道DATABASE_URL

    datasources:
      default:
        url: ${JDBC_DATABASE_URL}
        username: ${JDBC_DATABASE_USERNAME}
        password: ${JDBC_DATABASE_PASSWORD}
        driverClassName: org.postgresql.Driver
    

    【讨论】:

      【解决方案3】:

      很高兴您找到了解决方案。在任何情况下。我们可以读取该环境变量并通过 :,@ 拆分该 DATABASE_URL 并找到主机以及用户名和密码。

      【讨论】:

        猜你喜欢
        • 2011-08-29
        • 2017-12-18
        • 2015-05-03
        • 1970-01-01
        • 2010-11-22
        • 1970-01-01
        • 1970-01-01
        • 2011-03-11
        • 1970-01-01
        相关资源
        最近更新 更多