This post is over 6 months old. Some details, especially technical, may have changed.

Activate on Heroku

Activate is an object persistence framework for Scala. Unlike an ORM that openly tries to map DB concepts to objects Activate goes up a further level making the persistence aspect almost completely transparent. You work with objects and in doing so persistence happens as a side effect. For example given a class that extends the Entity trait,

class Person(var name: String, var age: Int)

We can create and persist this instance like so

transactional {
  new Person("James", 33)
}

Updating it will result in the persisted state of the instance being mutated as well. Activate uses the concurrency model of Software Transactional Memory at its core. As there is often some discrepencies between the conceptual model the database domain and objects Activate uses Dialects that handle the translation between the two (for example persisting an object with a List of Ints in a relational database that doesn't support array columns). In fact persistence is abstracted suitably that it becomes completely pluggable - use a document store like Mongo or a relational store like Postgres. Activate attempts to make this irrelevant.

I want to caveat all of this with the fact I'm not an Activate expert. I've succesfully used it in small volume projects and it's allowed me to be pretty productive. Which leads me to onto using it with Heroku.

Adapting Activate for Heroku

I have used Activate on 2 projects hosted on Heroku recently and I wanted to share a snippet that I wrote for the first one that I've found useful in the second. When you use Activate you need to create a Context that configures Activate for your application domain. One thing you need to set is the storage mechanism. On Heroku I used the provided Postgres instance which is made available to your application via the DATABASE_URL environment variable. So in JDBC based applications you need to coerce this into a JDBC connection string. To do this in Activate I used the code below which may come in useful for people wanting to do the same thing.

object PersistenceContext extends ActivateContext with Config {
  val storage = new PooledJdbcRelationalStorage {
        val uri        = new URI(System.getenv("DATABASE_URL"))
        val jdbcDriver = "org.postgresql.Driver"
        val user       = uri.getUserInfo.split(":").head
        val password   = uri.getUserInfo.split(":").last
        val url        = s"jdbc:postgresql://${uri.getHost()}:${uri.getPort()}${uri.getPath()}?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory"
        val dialect    = postgresqlDialect
      }
}
Published in Scala on December 11, 2013