Я пытаюсь реализовать отношение «один ко многим», используя Squeryl, и следуя инструкциям на их сайте .
В документации приведен следующий пример:
object SchoolDb extends Schema {
val courses = table[Course]
val subjects = table[Subject]
val subjectToCourses =
oneToManyRelation(subjects, courses).
via((s,c) => s.id === c.subjectId)
}
class Course(val subjectId: Long) extends SchoolDb2Object {
lazy val subject: ManyToOne[Subject] = SchoolDb.subjectToCourses.right(this)
}
class Subject(val name: String) extends SchoolDb2Object {
lazy val courses: OneToMany[Course] = SchoolDb.subjectToCourses.left(this)
}
Я считаю, что любые вызовы Course.subject
или Subject.courses
должны быть включены в транзакцию. Тем не менее, одна из моих целей при использовании ORM - скрыть эти детали от абонентов. Поэтому я не хочу, чтобы вызывающий код обернул вызов этих полей в транзакции.
Похоже, что если я изменю пример, чтобы обернуть ленивую функцию инициализации в транзакции, вот так:
class Subject(val name: String) extends SchoolDb2Object {
lazy val courses: OneToMany[Course] = {
inTransaction {
SchoolDb.subjectToCourses.left(this)
}
}
Я получаю следующее исключение:
Exception in thread "main" java.lang.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'
at scala.Predef$.error(Predef.scala:58)
at org.squeryl.Session$$anonfun$currentSession$1.apply(Session.scala:111)
at org.squeryl.Session$$anonfun$currentSession$1.apply(Session.scala:111)
at scala.Option.getOrElse(Option.scala:104)
at org.squeryl.Session$.currentSession(Session.scala:110)
at org.squeryl.dsl.AbstractQuery.org$squeryl$dsl$AbstractQuery$$_dbAdapter(AbstractQuery.scala:116)
at org.squeryl.dsl.AbstractQuery$$anon$1.<init>(AbstractQuery.scala:120)
at org.squeryl.dsl.AbstractQuery.iterator(AbstractQuery.scala:118)
at org.squeryl.dsl.DelegateQuery.iterator(DelegateQuery.scala:9)
Но, как я уже сказал, если я включаю вызывающего в транзакцию, то все работает.
Итак, как я могу инкапсулировать тот факт, что этот объект поддерживается базой данных в самом объекте?