1
votes

I cannot connecting to heroku database, when I deploy my app to heroku I getting this on logs:

[localhost-startStop-1] WARN org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [path/DataBaseConfig.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

My database config:

public class DataBaseConfig {

@Resource
private Environment env;

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws URISyntaxException{
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();

    em.setDataSource(dataSource());
    em.setPackagesToScan(env.getRequiredProperty("db.entity.package"));
    em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    em.setJpaProperties(getHibernateProperties());

    return em;
}

@Bean
public BasicDataSource dataSource() throws URISyntaxException {
    URI dbUri = new URI(System.getenv("jdbc:postgresql://user:password@Host:5432/databaseName"));

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

    BasicDataSource basicDataSource = new BasicDataSource();
    basicDataSource.setUrl(dbUrl);
    basicDataSource.setUsername(username);
    basicDataSource.setPassword(password);

    return basicDataSource;
}
}

What I do wrong?

3
Try to use System.getenv("DATABASE_URL") - Ali Dehghani
I built a library to make this easy: stackoverflow.com/a/56115257/2873507 - Vic Seedoubleyew

3 Answers

1
votes

Heroku uses DATABASE_URL environment variable to store the location of your primary database. So replace:

System.getenv("jdbc:postgresql://user:password@Host:5432/databaseName")

With:

System.getenv("DATABASE_URL")
1
votes

If you are using the standard Java buildpack you can replace the code in your dataSource method with this:

String dbUrl = System.getenv("JDBC_DATABASE_URL");
String username = System.getenv("JDBC_DATABASE_USERNAME");
String password = System.getenv("JDBC_DATABASE_PASSWORD");

BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setUrl(dbUrl);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);

return basicDataSource;

For more information see the Heroku documentation on Connecting to Relational Databases on Heroku with Java

0
votes

It seems like you're using Spring! This answer is for Spring Boot users

Apart from DATABASE_URL, which is always there, Heroku creates 3 environment variables at Runtime. They are:

JDBC_DATABASE_URL
JDBC_DATABASE_USERNAME
JDBC_DATABASE_PASSWORD

As you may be aware, Spring Boot will automatically configure your database if it finds spring.datasource.* properties in your application.properties file. Here is an example of my application.properties

spring.datasource.url=${JDBC_DATABASE_URL}
spring.datasource.username=${JDBC_DATABASE_USERNAME}
spring.datasource.password=${JDBC_DATABASE_PASSWORD}
spring.jpa.show-sql=false
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update

Hibernate / Postgres Dependencies

In my case I'm using Hibernate (bundled in spring-boot-starter-jpa with PostgreSQL, so I needed the right dependencies in my build.gradle:

dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile('org.postgresql:postgresql:9.4.1212')
}