Wednesday, April 2, 2008

Evolution of JPA from Lift

Edit: Forgot that I could use RequestVar. Also, Look at my next post for a further evolution of the Model object

Well, with some suggestions and info from David and Viktor I've started overhauling my use of JPA from within Lift. First and foremost, I've added in support for an EntityManager-per-request. This requires a little setup and utility class in my case:


object Model {
def createEM() = // fill this in however you want: JNDI, local Persistence, etc

// functions for setting a per-request entity manager
object emVar extends RequestVar[EntityManager](null)
def em = emVar.is

def wrapEM(f : => Unit, msg : String) : Unit = {
try {
f
} catch {
case e : Exception => this.error("Unexpected exception", e); S.error(msg)
}
}
}


The wrapEM method is something I've put together to make my code a little more concise when all I want to do is display an error when something goes wrong. The real meat of EM-per-session happens in Boot:


// Set up a LoanWrapper to automatically instantiate and tear down the EntityManager on a per-request basis
S.addAround(List(
new LoanWrapper {
def apply[T] (f : => T): T = {
val em = Model.createEM()

// Add EM into S scope
Model.emVar(em)

try {
f
} finally {
em.close()
}
}
}
))

1 comment:

Mateusz said...

some sample code of usage? would be very helpful.