Andrea
Andrea

Reputation: 20493

Avoiding Squeryl transaction in Play! controllers

I am learning Play! and I have followed the To do List tutorial. Now, I would like to use Squeryl in place of Anorm, so I tried to translate the tutorial, and actually it works.

Still, there is one little thing that irks me. Here is the relevant part of my model

def all: Iterable[Task] = from(tasks) {s => select(s)}

and the corresponding action in the controller to list all tasks

def tasks = Action {
    inTransaction {
        Ok(views.html.index(Task.all, taskForm))
    }
}

The view contains, for instance

<h1>@tasks.size task(s)</h1>

What I do not like is that, unlike in the methods to update or delete tasks, I had to manage the transaction inside the controller action.

If I move inTransaction to the all method, I get an exception,

[RuntimeException: No session is bound to current thread, a session must be created via Session.create and bound to the thread via 'work' or 'bindToCurrentThread' Usually this error occurs when a statement is executed outside of a transaction/inTrasaction block] 

because the view tries to obtain the size of tasks, but the transaction is already closed at that point.

Is there a way to use Squeryl transaction only in the model and not expose these details up to the controller level?

Upvotes: 1

Views: 886

Answers (1)

viktortnk
viktortnk

Reputation: 2757

Well. It's because of lazy evaluations on Iterable that require session bound (size() method). This might work if you turn Iterable into List or Vector (IndexedSeq) I suppose.

from(tasks)(s => select(s)).toIndexedSeq //or .toList

Upvotes: 3

Related Questions