2016-10-13 10 views
0

私はSpringでhibernateを設定しようとしています。私が得ることができないことに気付きました。
Bean.getBean(GenericDao.class).getCurrentSession();私はクローズセッションのみ取得できます。
openSession()メソッドでも同じことをやります - 有効なセッションを受け取ります。
質問は次のとおりです:なぜですか?私はGoogleで研究していますが、回答が見つかりませんでした。誰か知っていますか?なぜSpring以外のセッションが閉じられるのでしょうか?Context

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Primary; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 

import java.io.Serializable; 
import java.util.List; 

@Transactional (propagation = Propagation.REQUIRED, rollbackFor = { Throwable.class }) 
public abstract class GenericDao { 

    @Autowired 
    protected SessionFactory sessionFactory; 

    public Session getCurrentSession() { 
     return sessionFactory.getCurrentSession(); 
    } 

    public Session openSession() { 
     return sessionFactory.openSession(); 
    } 

    public void saveOrUpdate(final Serializable object) { 
     getCurrentSession().saveOrUpdate(object); 
    } 

    public void delete(final Serializable object) { 
     getCurrentSession().delete(object); 
    } 

    public void save(final Serializable object) { 
     getCurrentSession().save(object); 
    } 

    public void update(final Serializable object) { 
     getCurrentSession().update(object); 
    } 

    public void merge(final Serializable object) { 
     getCurrentSession().merge(object); 
    } 

    @SuppressWarnings ("unchecked") 
    public <T> List<T> list(final Class<T> clazz) { 
     return getCurrentSession().createCriteria(clazz).list(); 
    } 

    @SuppressWarnings ("unchecked") 
    public <T> T get(final Class<T> clazz, final Serializable id) { 
     return (T) getCurrentSession().get(clazz, id); 
    } 

} 

@Repository 
@Primary 
class GenericDaoImpl extends GenericDao { 

} 

答えて

1

1)getCurrentSession()方法を使用してコンテキストに結合したセッションを返すからです。しかし、これが機能するためには、以下のようにハイバネート設定ファイルに設定する必要があります。

<property name="hibernate.current_session_context_class">thread</property> 

thread contextは現在のスレッドを意味します。デフォルト値はjtaです。コンテキストとは、既存のjtaトランザクションを意味します。
このセッションオブジェクト(getCurrentSession()を使用してフェッチ)は、ハイバネートコンテキストに属しているため、これを閉じる必要はありません。 SessionFactoryが閉じられると、このセッションオブジェクトは閉じられます。

getCurrentSession()は、シングルスレッド環境で使用する必要があります。

2)openSession()メソッドは常に新しいセッションを開きます。すべてのデータベース操作が完了したら、このセッションオブジェクトを閉じる必要があります。 マルチスレッド環境では、リクエストごとに新しいセッションを開く必要があります。

安全とHibernateのSession &その使用をスレッド化に関連する詳細については、)(HibernateはgetCurrentSessionで使用するセッションの範囲を決定するために、現在のコンテキストクラスの概念を使用していますthis.

+0

これは、春の中で生まれたコンテキストで、セッションが 'getCurrenSession()'メソッドから得られることは不可能であることを意味します。私はあなたを正しく理解しましたか? – Dante

+1

あなたのケースでは、Springによってhibernateコンテキストが管理されます。そして、 'getCurrenSession()'メソッドからセッションを取得することは可能ですが、 'hibernate.current_session_context_class'プロパティ値を適切に設定する必要があります。つまり、セッションをフェッチする前にセッションを閉じる可能性のある既存のjtaトランザクション(セッション)です。 –

+0

さて、状況がより明確になった...返信いただきありがとうございます。私はそれを確認します – Dante

1

参照してください。純粋なHibernateでは、セッションがスレッドにバインドされるスレッドになる可能性があります。セッションがJTA UserTransactionにバインドされているjta

Springで使用する場合、hibernate.current_session_context_classプロパティを指定する必要はありません。 SpringSessionContext。これは、使用しているPlatformTransactionManagerを使用して、進行中のトランザクションにバインドします。

SessionFactory.getCurrentSession()を使用するには、コールが@Transactionalメソッド内にあることを確認します。そうでない場合は動作しません。したがって、openSessionあなたが@Annotationまたはトランザクションを構成した場合
@SuppressWarnings ("unchecked") public <T> List<T> list(final Class<T> clazz) { return getCurrentSession().createCriteria(clazz).list(); }
:)

+0

申し訳ありませんが、より明確にすることができますか、この情報を見つけたリソースへのリンクを教えてください。直感的に私はこれが私の質問に答えていることを理解していますが、私は最初の2つのパラグラフ – Dante

1

@Transactionalは、開口部の責任を取り、クローズSessionFactoryの、あなたは通りのOpenSessionなしgetCurrentSessionを使用することができます。こことしてxmlファイル:
<bean id="sessionFactory" class="..."
</bean>

<tx:annotation-driven proxy-target-class="true" transaction-manager="txManager" /> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
と@Transationalと@Autowiredとあなたがそうであるように、あなたが取引を設定しない場合、あなたはのOpenSessionを(使用することができます

OKです)のみ、あなたがセッションを終了したいときにcloseSessionを追加する

関連する問題