0

返されたオブジェクトのメンバーであるbag/Collectionにアクセスしようとすると、「ロールのコレクションを遅延初期化できませんでした」という例外をスローする休止状態のDAOがあります。

例外をスローする問題の範囲を理解しています。Hibernateは私のオブジェクトを返し、コレクションの場合はプロキシオブジェクトを返します。呼び出し元で、これらのプロキシオブジェクトにアクセスしようとすると、休止状態のセッションが期限切れになったため、この例外がスローされます。

私が知りたいのは、アノテーションを使用してセッションが期限切れにならないようにするにはどうすればよいですか?出来ますか?

たとえば、私の呼び出しメソッドが次の場合:

@RequestMapping("refresh.url")
public ModelAndView refresh(HttpServletRequest request, HttpServletResponse response, int id) throws Exception {
    TestObject myObj = testObjDao.get(id);
    // throws the exception
    myObj.getCollection();

アノテーションを使用してこの例外を防ぐにはどうすればよいですか?解決策の1つは、コールバックを介してHibernateセッションを拡張することです。これは、擬似コードでは次のようになります。

@RequestMapping("refresh.url")
public ModelAndView refresh(HttpServletRequest request, HttpServletResponse response, int id) throws Exception {
    session = get hibernate session...
    session.doInSession(new SessionCallback() {
        TestObject myObj = testObjDao.get(id);
        // no longer throws the exception
        myObj.getCollection();
    });

しかし、これは、コレクションにアクセスする必要のあるすべての関数に含まれているため、かなり繰り返しのようです。そこに@Transactionalアノテーションをたたくだけで、それを実行する方法はありませんか?のように:

@RequestMapping("refresh.url")
@Transactional  // this doesn't extend the session to this method?
public ModelAndView refresh(HttpServletRequest request, HttpServletResponse response, int id) throws Exception {
    TestObject myObj = testObjDao.get(id);
    // throws the exception
    myObj.getCollection();

これを私に説明するのにあなたの助けに感謝します。

4

3 に答える 3

1

Hibernate セッションは Web セッションとは異なり、有効期限がありません。それらは、コードまたはインフラストラクチャ (Spring など) によって手動で閉じられます。

セッションなしでDAOに入ると、まったく異なる例外が発生するため、セッションが最初にどのように作成されるかは明確ではありません( No Session Bound to Thread)。したがって、どういうわけか、セッションが作成されて閉じられます。私の推測では、DAO はインターセプターを介して@Transactional、またはインターセプターを介してトランザクション化されているため、セッションに入るとセッションが開始され、DAO メソッドを終了するとセッションが閉じられます。この場合、@TransactionalDAO でのトランザクションの伝播が に設定されている限り、MVC メソッドを配置しても機能しPROPAGATION_REQUIREDます。

ただし、 によって注釈が付けられたメソッドの外にコレクションを運ぶことはできないことに注意してください@Transactional。たとえば、http セッションに配置しないでください。それが必要な場合は、特別な DTO オブジェクトを使用してデータをコピーすることを検討してください。

于 2011-06-12T05:22:30.220 に答える
1

次のことを行う必要があります。

1) Spring にトランザクションを管理させます。

ここで詳細を読むことができます: http://www.mkyong.com/spring/spring-aop-transaction-management-in-hibernate/

そしてここ:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative

2) 遅延読み込み:

Hibernate からオブジェクトをフェッチすると、すべての遅延関連付けがプロキシとして返され、プロキシ クラスにアクセスすると、Hibernate セッションが閉じているため例外が発生します。

解決策は、View Filter/Interceptor で open Session を使用することです。

http://www.paulcodding.com/blog/2008/01/21/using-the-opensessioninviewinterceptor-for-spring-hibernate3/

正確には次のようになります。

<mvc:interceptors>
<bean class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
</mvc:interceptors>

それが役に立てば幸い。

于 2011-06-11T15:17:27.190 に答える
0

私が使用した解決策は、DAO のコレクションで @LazyCollection アノテーションを使用することでした。

@OneToMany(mappedBy = "<something here>", cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.FALSE)
于 2011-07-23T19:51:33.830 に答える