Skip to content

Instantly share code, notes, and snippets.

@mlecoutre
Created November 16, 2012 15:25
Show Gist options
  • Save mlecoutre/4088178 to your computer and use it in GitHub Desktop.
Save mlecoutre/4088178 to your computer and use it in GitHub Desktop.
JPA on Heroku without Spring

When creating a DEV instance of postgreSQL on heroku, heroku create an environment variable named "DATABASE_URL" that contains url, user and password. As we are in a cloud environment, your persistence.xml file should not contain any reference to a specific host, port or user/password account. It can change without any warning.

Unfortunately, this variable is not compliant with the JDBC format because HEROKU is not done just for the JAVA. So we need to translate this generic URL into a valid JDBC URL and extract user password You can found on the web a good example with Spring, but i've not found anything without it.

So here is a snippet of code that you can use in a ServletContextListener to initialize the EntityManagerFactory. (you will found it in org.mat.nounou.servlets.EntityManagerLoaderListener in this application).

String databaseUrl = System.getenv("DATABASE_URL");
StringTokenizer st = new StringTokenizer(databaseUrl, ":@/");
dbVendor = st.nextToken(); //if DATABASE_URL is set
userName = st.nextToken();
password = st.nextToken();
host = st.nextToken();
port = st.nextToken();
databaseName = st.nextToken();
jdbcUrl = String.format("jdbc:postgresql://%s:%s/%s?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory", host, port, databaseName);
Map<String, String> properties = new HashMap<String, String>();
properties.put("javax.persistence.jdbc.url", databaseUrl );
properties.put("javax.persistence.jdbc.user", userName );
properties.put("javax.persistence.jdbc.password", password );
properties.put("javax.persistence.jdbc.driver", "org.postgresql.Driver");
properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
emf = Persistence.createEntityManagerFactory("default", properties);

So, the xml persistence file should look like below.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="default">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.archive.autodetection" value="class"/>
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>
@AHerbel
Copy link

AHerbel commented Jul 6, 2017

Heroku throws me a "No persistence provider for EntitiyManager named default" when i try to instantiate the connection... any idea?? Any help would be great and really appreciated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment