Hi, Derek,
Have you considered making ScalaEntityManager a trait that can be mixed into
something that provides an EntityManager, rather than an abstract class
decorating one? I've taken that approach with good results; I think it makes
it a bit more flexible with respect to how the underlying EntityManager is
created.
I've attached the version I've been working with.
Kris
On Fri, Dec 12, 2008 at 4:28 PM, Derek Chen-Becker <[email protected]>wrote:
> I've reworked it a little and put it into its own project:
>
> http://github.com/dchenbecker/scalajpa/tree/master
>
> I've broken things down just a bit and added some more abstract classes to
> make it easier to use. In particular, now there's a LocalEM class that uses
> java.persistence.Persistence to retrieve the EM, and a JndiEM class that
> uses JNDI. Under the test source directory is an example of how to integrate
> with Lift, similar to how it's been done up to now. One thing I'm thinking
> about doing is reworking it a bit so that ScalaEntityManager becomes a
> per-instance usage, in case people want to use these classes outside of
> Lift. Right now it's very geared toward using a singleton accessor and using
> a per-thread management of instances. Please send me any questions or
> comments.
>
> Cheers,
>
> Derek
>
> PS - I'm going to talk to David B. to see if this can be hosted as a maven
> module on scala-tools.org so that you can just drop it in your POM in the
> future.
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Lift" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---
package com.gaiam.gcsi.model
import java.util.{Date,Calendar}
import javax.persistence._
import net.liftweb.http.RequestVar
import net.liftweb.util.{Can,Full,Empty}
import scala.collection.jcl.IterableWrapper
import scala.collection.jcl.Conversions._
object JPA {
implicit def collToWrapper[A](coll : java.util.Collection[A]) = new IterableWrapper[A] {
override def underlying = coll
}
def findToCan[A](f: => A): Can[A] =
try {
f match {
case null => Empty
case _ => Full(f)
}
} catch {
case e: NoResultException => Empty
}
}
trait ScalaEntityManager {
def em : EntityManager
// value added methods
def findOne[A](clazz: Class[A], id: Any) = JPA.findToCan[A](em.find[A](clazz, id).asInstanceOf[A])
def createQuery[A](queryString : String, params : Pair[String,Any]*) : ScalaQuery[A] = {
val q = new ScalaQuery[A](em.createQuery(queryString))
params.foreach(param => q.setParameter(param._1, param._2))
q
}
def createPageQuery[A](page : Int, pageSize : Int, queryString : String, params : Pair[String,Any]*) : ScalaQuery[A] = {
val q = createQuery[A](queryString, params : _*)
q.setMaxResults(pageSize)
q.setFirstResult(pageSize * page)
q
}
def createNamedQuery[A](queryName : String, params : Pair[String,Any]*) : ScalaQuery[A] = {
val q = new ScalaQuery[A](em.createNamedQuery(queryName))
params.foreach(param => q.setParameter(param._1, param._2))
q
}
// methods defined on Entity Manager
def persist(entity: AnyRef) = em.persist(entity)
def merge[T](entity: T): T = em.merge(entity)
def remove(entity: AnyRef) = em.remove(entity);
def find[A](clazz: Class[A], id: Any) = em.find[A](clazz, id).asInstanceOf[A]
def flush() = em.flush()
def setFlushMode(flushModeType: FlushModeType) = em.setFlushMode(flushModeType)
def refresh(entity: AnyRef) = em.refresh(entity)
def getFlushMode() = em.getFlushMode()
def createNativeQuery[A](sqlString: String) = new ScalaQuery[A](em.createNativeQuery(sqlString))
def createNativeQuery[A](sqlString: String, clazz: Class[A]) = new ScalaQuery[A](em.createNativeQuery(sqlString, clazz))
def createNativeQuery[A](sqlString: String, resultSetMapping: String) = new ScalaQuery[A](em.createNativeQuery(sqlString, resultSetMapping))
def close() = em.close()
def isOpen() = em.isOpen()
def getTransaction() = em.getTransaction()
def joinTransaction() = em.joinTransaction()
def clear() = em.clear()
def getDelegate() = em.getDelegate()
def getReference[A](clazz: Class[A], primaryKey: Any) = em.getReference[A](clazz, primaryKey)
def lock(entity: AnyRef, lockMode: LockModeType) = em.lock(entity, lockMode)
def contains(entity: AnyRef) = em.contains(entity)
}
class ScalaQuery[A](val query: Query) {
// value added methods
def findAll = getResultList()
def findOne = JPA.findToCan[A](query.getSingleResult.asInstanceOf[A])
def setParams(params : Pair[String,Any]*) = {params.foreach(param => query.setParameter(param._1, param._2)); this}
// methods defined on Query
def getResultList() = query.getResultList.asInstanceOf[java.util.List[A]].toList
def getSingleResult() = query.getSingleResult.asInstanceOf[A]
def executeUpdate() = query.executeUpdate()
def setMaxResults(maxResult: Int) = {query.setMaxResults(maxResult);this}
def setFirstResult(startPosition: Int) = {query.setFirstResult(startPosition); this}
def setHint(hintName: String, value: Any) = {query.setHint(hintName, value); this}
def setParameter(name: String, value: Any) = {query.setParameter(name, value); this}
def setParameter(position: Int, value: Any) = {query.setParameter(position, value); this}
def setParameter(name: String, value: Date, temporalType: TemporalType) = {query.setParameter(name, value, temporalType); this}
def setParameter(position: Int, value: Date, temporalType: TemporalType) = {query.setParameter(position, value, temporalType); this}
def setParameter(name: String, value: Calendar, temporalType: TemporalType) = {query.setParameter(name, value, temporalType); this}
def setParameter(position: Int, value: Calendar, temporalType: TemporalType) = {query.setParameter(position, value, temporalType); this}
def setFlushMode(flushMode: FlushModeType) = {query.setFlushMode(flushMode); this}
}