Cloud Zone is brought to you in partnership with:

The American Dream Realized: NYC-based Java Consultant. Author of Play Framework Mods Elastic Search, RabbitMQ. JavaLobby Featured MVB Writer. I blog at and tweet at Felipe is a DZone MVB and is not an employee of DZone and has posted 13 posts at DZone. View Full User Profile

Step-by-Step for a Simple Twitter with Play Framework, AJAX, CRUD and Heroku

  • submit to reddit
On August 31st, 2011: I will have the great honor to present our beloved Play Framework at Salesforce's Dreamforce conference here in San Francisco, CA. If you are attending, please feel free to check it out or just stop by to say hello. Thank you Zenexity for the opportunity! I am always excited to help spread the word on this awesome framework!


So the big announcement is out---Heroku started offering native support to Play Framework applications! If you haven't heard it, checkout the post from Jesper Joergensen on Heroku's blog.


So for the presentation, I am setting up a very basic Twitter clone; it's meant to be simple yet it displays just enough of the productivity that Play! provides. I am gonna go through the steps to setup the demo application which should cover what was announced on Heroku's blog post but with a little more depth.



  • First step let's create the application

  • play new twitter



  • Add dependency to CRUD module (conf/dependencies.yml)

  • - play -> crud



  • Get the dependencies

  • play dependencies



  • IDE Integration

  • play eclipsify (for Eclipse), play idealize (for IntelliJ) or play netbeansify (for Netbeans).



  • Create Model (app/models/

  • package models;
    import java.util.Date;
    import java.util.List;
    import javax.persistence.Entity;
    import play.db.jpa.Model;
    public class Tweet extends Model {
    public String tweet;
    public Date createDate = new Date();
    public static List findLatest() {
    return Tweet.find("order by createDate desc").fetch();
    public String toString() {
    return this.tweet;



  • Define DB for JPA Models (conf/application.conf)

  • db=${DATABASE_URL}



  • Add Controller Actions (app/controllers/

  • package controllers;
    import java.util.List;
    import models.Tweet;
    import play.mvc.Controller;
    public class Application extends Controller {
    public static void index() {
    List tweets = Tweet.findLatest();
    public static void create(String msg) {
    Tweet tweet = new Tweet();
    tweet.tweet = msg;;
    public static void tweets() {
    List tweets = Tweet.findLatest();



  • Define Main View (app/views/Application/index.html)

  • #{extends 'main.html' /}
    #{set title:'Home' /}
    <!-- Create Tweet Form -->
    <form> <input name="tweet" type="text" />
    <input type="submit" value="Tweet" /> </form><!-- Latest Tweets List -->
    <ul> #{list tweets}
    <li>${_.tweet} (${_.createDate.since()})</li><p><p>
    <!-- JS -->
    <script type="text/javascript">
    // Capture Form Submit Event
    $('form').submit(function() {
    // Define Create Action
    var createAction = #{jsAction @create(':tweet') /}
    // Call Create Action
    $.post(createAction({tweet: $('input:first').val()}), function(data) {
    // Prepend Results to the List
    // Don't let the browser redirect
    return false;



  • Define Create Action View (app/views/Application/create.html)

  • <!-- Single Item Render (after save action) -->
    <li><code>${tweet.tweet} (${tweet.createDate.since()})</li>



  • Create Unit Test for Tweet Model

  • import models.Tweet;
    import org.junit.Assert;
    import org.junit.Test;
    import play.test.UnitTest;
    public class TweetTest extends UnitTest {
    public void testModelSave() {
    long count = Tweet.count();
    Tweet t = new Tweet();
    t.tweet = "my sample tweet";;
    long count2 = Tweet.count();
    Assert.assertEquals(count + 1, count2);
  • Create CRUD Admin for Tweet Model

  • package controllers;
    public class Tweets extends CRUD {
  • Add Routes (conf/routes)

  • * /admin module:crud



  • Define Messages for CRUD Admin (conf/messages)

  • tweet=Tweet
    createDate=Date Created



  • Define Procfile

  • web: play run --%$FRAMEWORK_ID --http.port=$PORT -DusePrecompiled=$USE_PRECOMPILED -DDATABASE_URL=mem



  • Run in Development

  • play run --%dev -DusePrecompiled=false -DDATABASE_URL=mem



  • Create Application on Heroku

  • heroku create play-twitter --stack cedar



  • Setup Git Repository

  • git init; git add .; git commit -a -m "Initial Commit"; git remote add heroku



  • Setup Heroku Environment Variables

  • heroku config:add FRAMEWORK_ID=prod; heroku config:add USE_PRECOMPILED=true



  • Deploy to Heroku

  • git push heroku master



  • If anything went wrong you can always check the log

  • heroku logs



  • To Setup a Real Database on Heroku

  • heroku addons:add shared-database


    You can checkout a live demo here, the admin interface here or clone the source code on Github.


    Voila! Now Go Play!


    Originally posted at

    Published at DZone with permission of Felipe Oliveira, author and DZone MVB.

    (Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)


    John David replied on Thu, 2012/01/26 - 3:24am

    great post thanks!
    I’m trying to deploy a Play app on Heroku, I have a little problem with the shared database.
    When I deploy the app with “git push” I have this message :

    WARNING: Cannot replace DATABASE_URL in configuration (db=${DATABASE_URL})

    Did I miss something?

    Java Eclipse

    Comment viewing options

    Select your preferred way to display the comments and click "Save settings" to activate your changes.