Getting Started with Spring MVC Hibernate on Heroku

Last Updated: 15 June 2015


Table of Contents

This quickstart will get you going with a Spring MVC Hibernate application that uses a Postgres database service, deployed to Heroku. For general information on how to develop and architect apps for use on Heroku, see Architecting Applications for Heroku.

Sample code for the demo application is available on GitHub. Edits and enhancements are welcome. Just fork the repository, make your changes and send us a pull request.


Create a Java app that uses Spring MVC and Hibernate

If you don’t already have a Spring MVC Hibernate app, the easiest way to create one is with Spring Roo. Spring Roo is a RAD tool that lets you quickly build Spring MVC applications with a complete model, view and controller layer, including relational database integration.

Option 1. Clone the sample app

If you don’t want to install Spring Roo, you can clone the sample app:

$ git clone
Cloning into petclinic...
remote: Counting objects: 205, done.
remote: Compressing objects: 100% (100/100), done.
remote: Total 205 (delta 93), reused 205 (delta 93)
Receiving objects: 100% (205/205), 98.55 KiB, done.
Resolving deltas: 100% (93/93), done.

This will check out the completed app. Now you can skip forward to “Modify Database Configuration”.

Option 2. Create the app using Spring Roo

Install Spring Roo if you don’t already have it. Then create a directory for your app and generate the app using the clinic.roo script:

$ mkdir petclinic && cd petclinic
$ roo script --file clinic.roo

   / __ \/ __ \/ __ \
  / /_/ / / / / / / /
 / _, _/ /_/ / /_/ /
/_/ |_|\____/\____/    1.3.1.RELEASE [rev f787ce7]

Welcome to Spring Roo. For assistance press TAB or type "hint" then hit ENTER.
project --topLevelPackage com.springsource.petclinic
Created ROOT/pom.xml
Script required 41 second(s) to execute

By default, the generated app sets up the Hypersonic in-memory database. However, it is strongly recommended to use the same database locally as in production. So we will switch the application over to using Postgres with this Roo command:

$ roo persistence setup --provider HIBERNATE --database POSTGRES
Please update your database details in src/main/resources/META-INF/spring/
Updated ROOT/pom.xml [removed dependency org.hsqldb:hsqldb:; added dependency postgresql:postgresql:8.4-702.jdbc3]
Updated SRC_MAIN_RESOURCES/META-INF/spring/applicationContext.xml
Updated SRC_MAIN_RESOURCES/META-INF/persistence.xml

Finally, let’s create a git repo and commit this baseline of our application:

$ git init
$ echo target > .gitignore
$ git add .
$ git commit -m init

Modify database configuration

The web app generated by Spring Roo expects you to set database connection properties in the file src/main/resources/META-INF/spring/ However, it is not a good idea to hardcode database configuration into a file that is part of your project. Instead, we will edit the Spring configuration to read the configuration from an environment variable.

Heroku automatically provisions a small database when you create a Java application and sets the DATABASE_URL environment variable to a URL of the format


You can also provision a larger database service yourself using the heroku addons command. Either way, the database connection information will be stored in the DATABASE_URL variable.

Create a new URI spring bean initialized with this environment variable by adding this to src/main/resources/META-INF/spring/applicationContext.xml:

<bean class="" id="dbUrl">
    <constructor-arg value="${DATABASE_URL}"/>

Edit the dataSource section in src/main/resources/META-INF/spring/applicationContext.xml and replace the property place holders with the following:

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
    <property name="driverClassName" value="${database.driverClassName}"/>
    <property name="url" value="#{ 'jdbc:postgresql://' + @dbUrl.getHost() + ':' + @dbUrl.getPort() + @dbUrl.getPath() }"/>
    <property name="username" value="#{ @dbUrl.getUserInfo().split(':')[0] }"/>
    <property name="password" value="#{ @dbUrl.getUserInfo().split(':')[1] }"/>

To run your app locally set the DATABASE_URL variable in your local environment to point to your local postgres database, for example:

$ export DATABASE_URL=postgres://scott:tiger@localhost:5432/myapp

Add Jetty Runner

Jetty Runner lets you easily execute your web app as a standard Java application (without having to deploy it to a container). It’s a simple jar that you can copy down from the central Maven repository to the target directory as part of you build. We’ll use the maven-dependency-plugin to do this by adding the following plugin configuration at the end of the plugins section of pom.xml:


If Tomcat is required instead of Jetty, you can use webapp-runner as describe in Deploying Tomcat-based Java Web Applications with Webapp Runner.

Declare process types with Procfile

Use a Procfile, a text file in the root directory of your application, to explicitly declare what command should be executed to start a web dyno. In this case, you want to execute the Jetty Runner.

Here’s a Procfile for the sample app we’ve been working on:

web: java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war

This declares a single process type, web, and the command needed to run it. The name “web” is important here. It declares that this process type will be attached to the HTTP routing stack of Heroku, and receive web traffic when deployed.

Optionally Choose a JDK

By default, OpenJDK 1.8 is installed with your app. However, you can choose to use a newer JDK by specifying java.runtime.version=1.7 in the file.

Here’s what a file looks like:


You can specify 1.6, 1.7, or 1.8 (1.8 is in beta) for Java 6, 7, or 8 respectively.

Run your app locally

Let’s run the app locally first to test that it all works. You must have a Postgres database up and running and accessible on the DATABASE_URL you specified above.

Build your app

$ mvn package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building petclinic 0.1.0.BUILD-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] --- maven-dependency-plugin:2.3:copy (default) @ petclinic ---
[INFO] Configured Artifact: org.mortbay.jetty:jetty-runner:7.4.5.v20110725:jar
[INFO] Copying jetty-runner-7.4.5.v20110725.jar to /Users/jjoergensen/dev/tmp/spring-roo-petclinic/target/dependency/jetty-runner.jar
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 20.466s
[INFO] Finished at: Mon Aug 29 20:56:03 PDT 2011
[INFO] Final Memory: 9M/81M
[INFO] ------------------------------------------------------------------------

Start your app

Note: you can also start your app using foreman to execute the Procfile. Read more about foreman and Procfiles.

$ java -jar target/dependency/jetty-runner.jar target/*.war

Test it

Go to http://localhost:8080 and test it out by creating a new record.

Store your app in Git

We now have the application with it’s dependencies declared in pom.xml, and a Procfile. Let’s put it into Git:

$ git add .
$ git commit -m "Ready to deploy"

Deploy your application to Heroku

Create the app:

$ heroku create
Creating high-lightning-129... done, stack is cedar |
Git remote heroku added

Deploy your code:

$ git push heroku master
Counting objects: 227, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (117/117), done.
Writing objects: 100% (227/227), 101.06 KiB, done.
Total 227 (delta 99), reused 220 (delta 98)

-----> Heroku receiving push
-----> Java app detected
-----> Installing Maven 3.2.3..... done
-----> executing .maven/bin/mvn -B -Duser.home=/tmp/build_1jems2so86ck4 -DskipTests=true clean install
       [INFO] Scanning for projects...
       [INFO] ------------------------------------------------------------------------
       [INFO] Building petclinic 0.1.0.BUILD-SNAPSHOT
       [INFO] ------------------------------------------------------------------------
       [INFO] ------------------------------------------------------------------------
       [INFO] ------------------------------------------------------------------------
       [INFO] Total time: 36.612s
       [INFO] Finished at: Tue Aug 30 04:03:02 UTC 2011
       [INFO] Final Memory: 19M/287M
       [INFO] ------------------------------------------------------------------------
-----> Discovering process types
       Procfile declares types -> web
-----> Compiled slug size is 62.7MB
-----> Launching... done, v5 deployed to Heroku

Congratulations! Your web app should now be up and running on Heroku.

Visit your application

You’ve deployed your code to Heroku, and specified the process types in a Procfile. You can now instruct Heroku to execute a process type. Heroku does this by running the associated command in a dyno - a lightweight container which is the basic unit of composition on Heroku.

Let’s ensure we have one dyno running the web process type:

$ heroku ps:scale web=1

You can check the state of the app’s dynos. The heroku ps command lists the running dynos of your application:

$ heroku ps
=== web: `java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war`
web.1: up for 6m

Here, one dyno is running.

We can now visit the app in our browser with heroku open.

$ heroku open
Opening pure-window-800... done

Dyno sleeping and scaling

By default, your app is deployed on a free dyno. Free dynos will sleep after a half hour of inactivity and they can be active (receiving traffic) for no more than 18 hours a day before going to sleep.  If a free dyno is sleeping, and it hasn’t exceeded the 18 hours, any web request will wake it. This causes a delay of a few seconds for the first request upon waking. Subsequent requests will perform normally.

To avoid dyno sleeping, you can upgrade to a hobby or professional dyno type as described in the Dyno Types article. For example, if you migrate your app to a professional dyno, you can easily scale it by running a command telling Heroku to execute a specific number of dynos, each running your web process type.

View the logs

Heroku treats logs as streams of time-ordered events aggregated from the output streams of all the dynos running the components of your application. Heroku’s Logplex provides a single channel for all of these events.

View information about your running app using one of the logging commands, heroku logs:

$ heroku logs
2012-09-11T19:12:27+00:00 app[web.1]: 2012-09-11 19:12:27,217 [main] INFO org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'petclinic': initialization completed in 573 ms
2012-09-11T19:12:27+00:00 app[web.1]: 2012-09-11 19:12:27.240:INFO::Started SelectChannelConnector@ STARTING
2012-09-11T19:12:28+00:00 heroku[web.1]: State changed from starting to up

Next steps

  • Visit the Java category to learn more about developing and deploying Java applications.
  • Read How Heroku Works for a technical overview of the concepts you’ll encounter while writing, configuring, deploying and running applications.