2

我正在尝试使用 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.subjectSubject.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)

但是,就像我说的,如果我将调用者包装在事务中,那么一切正常。

那么,我怎样才能在对象本身中封装这个对象由数据库支持的事实呢?

4

1 回答 1

1

我假设您在调用课程对象时遇到此错误?

我不太了解 Squeryl 的工作原理,但我相信 OneToMany[Course] 是一个活动对象。这意味着对课程对象的调用需要一个会话,因为任何调用都可能懒惰地进入数据库以获取数据。

您如何组织这取决于您使用的应用程序类型。在 Web 应用程序中,添加过滤器(第一个入口点)来启动和停止事务通常是有意义的。在一个 GUI 客户端中,比如一个 swing 应用程序,在接收到用户交互的地方启动事务是一个很好的解决方案。这样,您可以获得不长的事务,并且还延伸了您希望以原子方式执行的调用(完全或根本不执行)。

于 2011-01-28T07:14:53.197 回答