2

この質問が何度も出されていることは理解していますが、ほとんどの人は私の問題を説明できません:

@RequestMapping("/testing")
public String testing(HttpServletRequest request, final ModelMap model) 
{
    Transaction ut = session.openSession().beginTransaction();

    session.getCurrentSession(); // error here

    ut.commit();

    return "testing";
}

エラーが発生する理由

Could not obtain transaction-synchronized Session for current thread.

メソッドに で注釈を付けると@Transactional、完全に正常に機能します。私は@EnableTransactionManagement私の春の文脈にあるからです。

getCurrentSessionとの違いを理解するために何か試してみたいopenSessionので、上記のテストケースを作成しました。

getCurrentSessionアクティブなトランザクション コンテキスト内で呼び出されますが、なぜまだエラーが発生するのですか?

コードはこちらから参照してください。

4

1 に答える 1

0

OK、長い間調査した結果、以下の段落を見逃していることがわかりました。

これらのコード スニペットは、通常のアプリケーションでは表示されません。致命的な (システム) 例外は、常に「先頭」でキャッチする必要があります。つまり、永続レイヤーで Hibernate 呼び出しを実行するコードと、RuntimeException を処理するコード (通常はクリーンアップと終了のみが可能) は別のレイヤーにあります。Hibernate による現在のコンテキスト管理では、SessionFactory にアクセスすることで、この設計を大幅に簡素化できます。例外処理については、この章で後述します。

したがって、実際に示されている例は、通常のシナリオでは機能しません...

私は以下のようにしなければなりません:

// BMT idiom with getCurrentSession()
try {
    UserTransaction tx = (UserTransaction)new InitialContext()
                            .lookup("java:comp/UserTransaction");

    tx.begin();

    // Do some work on Session bound to transaction
    factory.getCurrentSession().load(...);
    factory.getCurrentSession().persist(...);

    tx.commit();
}
catch (RuntimeException e) {
    tx.rollback();
    throw e; // or display error message
}

つまり、の使用はかなり制限されており、 (および特定の) トランザクションgetCurrentSessionで実行する必要があります。active

于 2016-10-03T01:32:36.323 に答える