Search code examples
javaspringherokuheroku-postgres

Spring do not see datasource on local but deployed on Horaku works fine


I'm doing Heroku tutorial https://devcenter.heroku.com/articles/getting-started-with-gradle-on-heroku and everything was fine until i can't run database in local instance.

I tried it in intelij and through the console ($heroku local web after build gradlew). I tried copy db from Heroku to local postgresDb but also failed.

    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Autowired
    private DataSource dataSource;

    @RequestMapping("/db")
    String db(Map<String, Object> model) {
        try (Connection connection = dataSource.getConnection()) {
            Statement stmt = connection.createStatement();
            stmt.executeUpdate("CREATE TABLE IF NOT EXISTS ticks (tick timestamp)");
            stmt.executeUpdate("INSERT INTO ticks VALUES (now())");
            ResultSet rs = stmt.executeQuery("SELECT tick FROM ticks");

            ArrayList<String> output = new ArrayList<String>();
            while (rs.next()) {
                output.add("Read from DB: " + rs.getTimestamp("tick"));
            }

            model.put("records", output);
            return "db";
        } catch (Exception e) {
            model.put("message", e.getMessage());
            return "error";
        }
    }

    @Bean
    public DataSource dataSource() throws SQLException, URISyntaxException {
        if (dbUrl == null || dbUrl.isEmpty()) {
            return new HikariDataSource();
        } else {
            HikariConfig config = new HikariConfig();
            config.setJdbcUrl(dbUrl);
            return new HikariDataSource(config);
        }
    }

I also tried to receive dbUrl from Heroku config

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";

After i go to /db page i receive HikariPool-1 - dataSource or dataSourceClassName or jdbcUrl is required. What am I doing wrong?


Solution

  • Use @Bean from tutorial. You must copy (or just create) .env file from heroku and add conection string becouse it isn't originally stored there but heroku treat it like it were.

    • In console get JDBC_DATABASE_URL by command (on windows) heroku run echo $JDBC_DATABASE_URL
    • Copy string from output
    • Paste this string into .env file in your project as variable JDBC_DATABASE_URL="your_conecction_string_copied_from_console"
    • console: heroku local web
    • profit :)

    shortcut script for windows:

    echo|set /p="JDBC_DATABASE_URL=" | heroku run echo $JDBC_DATABASE_URL >> .env