Hi clint,
If I follow your example, how to call both methods in one transaction, for example
db.withTransaction {
slickDAO.savePerson()
slickDAO.findPerson()
}
this gonna open session 3 times, and break the transaction
in real world, I think its common to call some DAO methods in one session or transaction in a part of our code, while in another part of our code we only we call one DAO method
Correct me if I'm wrong, actually Hibernate not did not survive from this problem too, they are also using threadlocal too to save session just like slick, so they are not safe in multi-thread environment.
I'm agre with you, I prefer slick over hibernate.
btw, this is my new approach as Christoper suggestion
case class Person(id: String, name: String)
trait PersonDAO {
def savePerson(id: String, name: String): Unit
def getPerson: (String, String)
}
object SlickPersonDAO extends PersonDAO {
import import scala.slick.driver.PostgresDriver.simple._
import Database.threadLocalSession // implicit session for all DAO methods, to "re-using" avaiable session on current thread
object PersonTable extends Table[(String, String)]("person") {
def personId = column[String]("id", O.NotNull)
def name = column[String]("name", O.NotNull)
def baseProjection = personId ~ name
def * = baseProjection
val findByName = createFinderBy(_.name)
}
// no (implicit s: Session) or "implicit s: Session =>" since we already import threadLocalSession
override def savePerson(id: Person, name: String): Unit {
PersonTable.insert(id, name)
}
override def getPerson: (String, String) =
PersonTable.findByName(name).firstOption
}
// somewhere in my application, now we are freely to call single method within a session
db.withSession {
slickDAO.getPerson("name")
}
// or call some DAO methods within a transaction
db.withTransaction {
val personData = slickDAO.getPerson("a name")
slickDAO.savePerson(personData._1, "newName")
}
btw,, I keep open my eyes for another approach
Regards,
Bandirsen
.