2011-01-28 1 views
2

私はSquerylを使用して、そしてinstructions on their siteの後にOne-To-Many関係を実装しようとしています。私はCourse.subjectまたはSubject.coursesニーズへの呼び出しがトランザクションにラップされることがわかりセッション/トランザクションの取得を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) 
} 

マニュアルは、次の例を示します。しかし、ORMを使用する私の目標の1つは、これらの詳細を発信者から隠すことです。そのため、私は呼び出しコードがトランザクション内でこれらのフィールドに呼び出しをラップする必要はありません。

のでようですが、私はトランザクションで怠惰なinit関数をラップする例を変更した場合ようだ:私が言ったように、

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) 

しかし:

class Subject(val name: String) extends SchoolDb2Object {  
    lazy val courses: OneToMany[Course] = { 
    inTransaction { 
     SchoolDb.subjectToCourses.left(this) 
    } 
} 

が、私は次の例外を取得します私がトランザクションで呼び出し元をラップすると、すべてが機能します。

したがって、このオブジェクトがオブジェクト自体のデータベースによってサポートされているという事実をカプセル化するにはどうすればよいですか?

答えて

1

コースオブジェクトの呼び出しでこのエラーが発生すると思いますか?

Squerylがどのように機能するかはよくわかりませんが、OneToMany [Course]はライブオブジェクトだと思います。つまり、コースオブジェクトの呼び出しはセッションを必要とします。これは、任意の呼び出しがデータを取得するためにデータベースに遅れて行く可能性があるためです。

これを整理する方法は、使用するアプリケーションの種類によって異なります。 Webアプリケーションでは、トランザクションを開始および停止するためのフィルタ(エントリの最初のポイント)を追加することがよくあります。 GUIクライアントでは、スイングアプリケーションと言います。ユーザーとのやりとりを受け取った時点でトランザクションを開始するのは良い解決策です。そうすれば、長時間ではないトランザクションを得ることができます。また、アトミックに実行されると予想されるコールに対しても(完全に、またはまったく)実行されます。

+0

まあ、私の例があまりにも単純すぎるかもしれません。実際には、私はsquerylドキュメントからの例を試していませんが、私のコードはそれほど複雑ではありません(構造の唯一の違いは、私の列が多いということです)。コンパニオンオブジェクト内の関数を呼び出すと、そのオブジェクトのインスタンスが取得され、その関数はトランザクションを使用しますが、カプセル化の観点からは、コンパニオンオブジェクトがバックアップされるクラスにリンクされているためDBによって。私のアプリケーションには実際にはユーザーのやりとりがありません(ただし、ユーザーはそれを起動します)。レポートを生成するだけです。 – pkaeding

+0

あなたがレポートを作成しているので、あなたは書き込みをしていないと思います。操作全体をトランザクションにパックする際に害があってはいけません。 – thoredge

関連する問題