integrate circumflex-orm into play 2.0 using scala

If you are like me and dont want to use the proposed orm anorm in play 2.0, you may want to use circumflex-orm (http://circumflex.ru/projects/orm/index.html) i give you a quick howto on the integration.

First, create a cx.properties in the conf folder of your project:

orm.connection.driver=com.mysql.Driver
orm.connection.url=jdbc:mysql://localhost/database
orm.connection.username=un
orm.connection.password=pw

Also add the dependency to your Build.scala file:

val appDependencies = Seq(
  "ru.circumflex" % "circumflex-orm" % "2.1"
)

Then create the class and it’s object:

class Task extends Record[Long, Task] with IdentityGenerator[Long, Task] {
  def this(name: String, description: String) = {
    this()
    this.name := name
    this.description := description
  }
 
  val id = "id".BIGINT.NOT_NULL.AUTO_INCREMENT
  val name = "name".VARCHAR(255).NOT_NULL
  val description = "description".TEXT.NOT_NULL
 
  def PRIMARY_KEY = id
  def relation = Task
}
 
object Task extends Task with Table[Long, Task] {
  def apply(name: String, description: String) = new Task(name, description)
  def unapply(t : Task) = Option(t.name(), t.description())
}

For more info about the fields and the usage of circumflex, look at the docs at their homepage please.

Finally you can retrieve with get for instance, it works without any additions.

val task = Task.get(1).get
println("name" + task.name())

But to save and insert you have to promote a context:

val task = new Task("foo","bar")
  Context.executeInNew {ctx =>
    println(task.save())
}

According to a gentle guy from circumflex this should belong into a filter, which must be put somewhere in the lifecycle usage of your app.
Please have a look at the google group discussion for more information about that:
https://groups.google.com/forum/?fromgroups#!topic/circumflex-scala/ma2uCVgPx1Q
But thats a topic for another day.

Easy, isn’t it? In the end i still could use anorm, or something similar besides it, if i need some complex sql’s to get done, but, as far as i can tell, circumflex should suffice for most of them.

Update:
Well, transaction management was no topic for another day. It turned out that without the Context from circumflex cache management did not work.

It is possible to save and retrieve, but, retrieval happens from the cache, and without the transaction-management the cache does not get updatet.

So, what you have to do is write your own action class like this:

import play.api.mvc.Action
import play.api.mvc.Request
import play.api.mvc.Result
import ru.circumflex.core.Context
 
case class ScircumflexOrmActionWrapper[A](action: Action[A]) extends Action[A] {
 
  def apply(request: Request[A]): Result = {
    Context.executeInNew { ctx =>
      action(request)
    }
  }
 
  lazy val parser = action.parser
}

And then call it like that:

def index = ScircumflexOrmActionWrapper { Action {
 
	val taskDbObj = Task AS "taskDb"
	val tasks = SELECT(taskDbObj.*).FROM(taskDbObj).ORDER_BY(taskDbObj.createdAt DESC).list
 
	Ok(html.task.index(tasks))
  }}

Now you should have a working solution.

6 Gedanken zu “integrate circumflex-orm into play 2.0 using scala

    • Hi, i quickly set up a repo at github:
      https://github.com/sveri/seiwomisa/
      This is the project i am working on, trying out scala with play and things.

      As i dont really have much time right now i just moved it up, it’s somewhat in an unorder, sorry for that, but it works at my place and you can get everything out there.

  1. Dear Sven,

    I followed your blogpost “integrate circumflex-orm into play 2.0 using scala” step by step but anyway I get an exception telling me c3po is “not able to acquire a resource from its primary factory or source”.

    I implemented ur solution on windows and linux, both fail. So I wonder what is wrong with my database configuration. Were there any issues ur not telling in your blogpost? I’ll append the stack trace.

    Cheers
    daniel


    play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[SQLException: Connections could not be acquired from the underlying database!]]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) [play_2.9.1.jar:2.0.1]
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1.jar:2.0.1]
    at akka.actor.Actor$class.apply(Actor.scala:311) [akka-actor.jar:2.0.1]
    at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1.jar:2.0.1]
    at akka.actor.ActorCell.invoke(ActorCell.scala:619) [akka-actor.jar:2.0.1]
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:196) [akka-actor.jar:2.0.1]
    Caused by: java.sql.SQLException: Connections could not be acquired from the underlying database!
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106) ~[c3p0-0.9.1.2.jar:0.9.1.2]
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:529) ~[c3p0-0.9.1.2.jar:0.9.1.2]
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) ~[c3p0-0.9.1.2.jar:0.9.1.2]
    at ru.circumflex.orm.SimpleConnectionProvider.openConnection(config.scala:164) ~[circumflex-orm-2.1.jar:na]
    at ru.circumflex.orm.Transaction.getConnection(config.scala:247) ~[circumflex-orm-2.1.jar:na]
    at ru.circumflex.orm.Transaction.execute(config.scala:264) ~[circumflex-orm-2.1.jar:na]
    Caused by: com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source.
    at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1319) ~[c3p0-0.9.1.2.jar:0.9.1.2]
    at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557) ~[c3p0-0.9.1.2.jar:0.9.1.2]
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477) ~[c3p0-0.9.1.2.jar:0.9.1.2]
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525) ~[c3p0-0.9.1.2.jar:0.9.1.2]
    at com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection(AbstractPoolBackedDataSource.java:128) ~[c3p0-0.9.1.2.jar:0.9.1.2]
    at ru.circumflex.orm.SimpleConnectionProvider.openConnection(config.scala:164) ~[circumflex-orm-2.1.jar:na]

    • Please have a look at my comment above, as i dont have much time right now i am sorry, i cannot help you much further than linking to my github account.

  2. Hello Sven,

    This is awesome. I’ve found when writing data access logic using Anorm is counter productive, cumbersome and sacrificing Database server’s portability feature. Once again, thanks for this helpful info.

    Cheers.

    • Yea, thats why i was looking for a different way to access the database. Seeing all that boilerplate being gone with scala and play 2.0, but being forced to write plain sql for every single access is not my understanding of modern development.
      It’s always good to be able to do so, if you need it, but most of the times it’s just to much.
      Glad you like it.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *


fünf + 5 =

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>