2011-06-22 7 views
5

私はStruts 2とHibernateを使用しています。私は、特定のアクションがいつ行われたかについての情報を格納するDateフィールドを持つシンプルなテーブルを持っています。この日付の値はjspに表示されます。 私が持っている問題は、hibernateがdbを更新した後、jspページが日付の値を更新しないということです。実施例のように:私は手動で(F5)更新するとHibernateのキャッシュ?

date1 = 22/06/11 15:00:00 
date2 = 22/06/11 16:00:00 

は、それはOKです - (すなわち、午後3時から午後4時まで)date1からdate2に日付値が変化します。しかし、私がリフレッシュし続ければ、JSPは一度date1とnext2のdate2を表示します。 私はhibernate.cfgに次き:

<property name="hibernate.cache.use_second_level_cache">false</property> 
<property name="hibernate.cache.use_query_cache">false</property> 

I)は(フラッシュ)(Hibernateの追い出しで実験しました。私は(はい、私は知っている - スクリプトレットは悪い習慣です)スクリプトレットを追加してみました:

<% 
    response.setHeader("Pragma", "no-cache"); 
    response.setHeader("Cache-Control", "no-cache"); 
    response.setDateHeader("Expires", 0); 
%> 

私は少しはここにこだわっている - すべてのヘルプは高く評価しました。

おかげで、 ダモ

EDIT: は、私はすべてのDAOを拡張DaoEngineクラスを、持っています。

public class DaoEngine 
{ 

    @SuppressWarnings("unchecked") 
    private static final ThreadLocal session = new ThreadLocal(); 
    private static final SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); 

    protected DaoEngine() 
    { 
    } 

    @SuppressWarnings("unchecked") 
    public static Session getSession() 
    { 
     Session hibSession = (Session) DaoEngine.session.get(); 
     if (hibSession == null) 
     { 
      hibSession = sessionFactory.openSession(); 
      DaoEngine.session.set(hibSession); 
     } 
     return hibSession; 
    } 

    protected void begin() 
    { 
     getSession().beginTransaction(); 
    } 

    protected void commit() 
    { 
     getSession().getTransaction().commit(); 
    } 

    @SuppressWarnings("unchecked") 
    protected void rollback() 
    { 
     try 
     { 
      getSession().getTransaction().rollback(); 
     } 
     catch (HibernateException e) 
     { 
     } 
     try 
     { 
      getSession().close(); 
     } 
     catch (HibernateException e) 
     { 
     } 
     DaoEngine.session.set(null); 
    } 

    @SuppressWarnings("unchecked") 
    public static void close() 
    { 
     getSession().close(); 
     DaoEngine.session.set(null); 
    } 

    public void clearAll() 
    { 
     getSession().clear(); 
    } 
} 
+1

Hibernateセッション(またはJPAエンティティマネージャ)の管理やクリーンアップにはどのようなメカニズムを使用していますか? –

答えて

4

しかし、私はさわやかに保つ場合、JSPは一度ように日付1と次回date2のを表示します。

リフレッシュすると、古いデータと新鮮なデータが切り替わります。

これは、通常、ThreadLocalからHibernateセッションを閉じて削除することができないために発生します。ほとんどのアプリケーションサーバーはスレッドプールからスレッドを再利用して要求を処理するため、古いセッションがThreadLocalから削除されないと再利用され、永続コンテキストがデータベースと同期しなくなります。

DaoEngineクラスでclose()メソッドを呼び出していることを確認してから、リクエストが終了するまで必ず実行してください。おそらく、サーブレット・フィルターまたはStruts2インターセプターのセッションを設定し、解除する必要があります。

+0

私はあなたのアドバイスに従って、ちょっと読んでみると、seesionFactory.openSession()は素晴らしい考えではないことが分かります。それを使用する場合は、セッションを管理するためのコードを提供する必要があります([セッションとトランザクション](http://community.jboss.org/wiki/SessionsAndTransactions#Transaction_demarcation_with_plain_JDBC "セッションとトランザクション")。私はopenSession()をgetCurrentSession()に置き換えてコードを変更しましたが、今は動作しますが、完璧ではありません - リクエストごとに新しいセッションを取得しますが、これは単なるモックアッププロジェクトですので、それはOKです。ありがとうSteven! –

+2

各リクエストの新しいセッションは、実際にはベストプラクティスです:) –

0

この切り替えは、古いセッションがThreadLocalから削除されないために発生します。これは2通りの方法で行うことができます: - 1.リクエストが終了する前にsession.close()を追加します。 2. spring管理クラスを使用して、自動的にseesionを処理します。

関連する問題