Tuesday, April 26, 2011

Moving to Siena from Play Framework JPA

I Recently built a REST service using the Play Framework and once complete I started looking for a place to deploy the app. Not having a hosted server that runs Java meant I needed a cloud solution and the first to come to mind was GAE. I have used GAE before but this was the first time with Play. (Play and GAE go great together btw.)

Having done little deployment planning from the beginning, it wasnt until a blew through the coding and did a successful deploy that I realized that JPA just doesn't seem to work well with Play's JPA (nothing against Play, GAE just does JPA differently). After a bit of reading that I had skipped past the first time it became evident that I needed to use the Play Siena Module with my GAE app. This turned out to be easier then I though but, I had to hunt around a little to piece together the details so I wanted to share the migration here. This should also be helpful if you are planning to use Siena from the start and already know Play's JPA.

Moving to Siena from the Play JPA was surprisingly simple, I spent more time thinking over weather I wanted to mess with it and looking up the details then actually doing it!

1. Install Siena into Play. (I'm assuming you have Play set up and GAE already installed.)
play install siena-1.5

2. Include in App.conf. Add Siena right under the GAE module like so.

# ---- MODULES ----
module.gae=${play.path}/modules/gae-1.4
module.siena=${play.path}/modules/siena-1.5


3. Change your Models from play.db.jpa.Model to siena.Model. Your just changing an import statement here.

//import play.db.jpa.Model;
import siena.Model;


4. Add an ID field. Play takes care of this for you in the Model but you'll have to add it in for Siena, or make a new Object to inherit from.

  @Id
  public Long id;


5. Update method calls. A few methods have slightly different names but they are pretty obvious and should slow you down.
  1. Model.save() calls become Model.insert()
  2. You'll need to change up your searching, I usually just code methods in the Model to wrap the search queries which means I only have to change the search code in one spot, the Model. Here's a sample of a new search:
  3. Model.all(MonitoredFeed.class).filter("suspended", false).fetch();
  4. Change findAll(), all() calls to Model.All(Your.class) or simply provide a helper method like below.(This could again go in some type of BaseModel reducing your code changes.)
  5. public static Query all() {     return Model.all(MonitoredFeed.class); }
6. Update your Test Fixtures! Of course you have to update the Tests! If your using Fixtures you'll just have to change your imports from Fixture to SienaFixture.

That's all there its to it! Now you can deploy your app on GAE!

1 comment:

  1. Reference to your 4 bullet :
    I get "SienaException occured : No valid @Id defined in class models.foo.Foo" if i am trying to extends from MyBasicModel.

    public abstract class MyBasicModel extends from SienaSupport {
    @Id
    public Long id;
    }

    if the definition of the "id" field is in the Foo class, no problem occurred.
    any ideas ?
    Thanks

    ReplyDelete