2011-06-22 12 views
5

Używam Struts 2 i Hibernate. Mam prostą tabelę z polem Data, która przechowuje informacje o tym, kiedy dana akcja miała miejsce. Ta wartość daty jest wyświetlana w moim jsp. Problem polega na tym, że po aktualizacji przez system hibernacji db, strona jsp nie aktualizuje wartości daty. Jako przykład robocza:Buforowanie hibernacji?

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

Kiedy odświeżyć ręcznie (F5) to jest to OK - zmiany wartości daty z date1 do date2 (czyli od 15:00 do 16:00). Ale jeśli będę dalej odświeżać, to jsp będzie pokazywał datę 1 i następną datę 2 i tak dalej. Mam następujących w moim hibernate.cfg:

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

eksperymentowałem z eksmitować Hibernate(), flush(). Próbowałem dodanie scriptlet (tak, wiem - scriptlets są złe praktyki):

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

Jestem nieco zakleszczony tutaj - Każda pomoc mile widziana.

Dzięki Damo

EDIT: Mam klasy DaoEngine, co wszyscy moi DAOs przedłużenia.

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

Jakiego mechanizmu używasz do zarządzania sesjami hibernacji i zarządzania nimi (lub menedżerami jednostek JPA)? –

Odpowiedz

4

Ale jeśli trzymać orzeźwiający, to JSP po raz pokazać date1 i następnym razem date2 i tak dalej.

Zakładam, że masz na myśli, że podczas odświeżania dane wyjściowe przełączają się między stałymi i świeżymi danymi?

Jeśli tak, zwykle jest to spowodowane brakiem zamknięcia i usunięcia sesji Hibernate z wątku LocalLocal. Większość serwerów aplikacji będzie ponownie wykorzystywać wątki z puli wątków do przetwarzania żądań, więc jeśli stara sesja nie zostanie usunięta z ThreadLocal, zostanie ponownie wykorzystana, a jej kontekst utrwalania nie będzie zsynchronizowany z bazą danych.

Upewnij się, że wywołujesz metodę close() na swojej klasie DaoEngine przed zakończeniem żądania. Prawdopodobnie powinieneś skonfigurować i oderwać sesje w filtrze serwletów lub przechwytywaczu Struts2.

+0

Poszedłem za twoją radą, przeczytaj trochę i okazało się, że seesionFactory.openSession() nie jest świetnym pomysłem. Jeśli go używasz, musisz podać kod do zarządzania sesją (jak wyjaśniono tutaj: [Sesje i transakcje] (http://community.jboss.org/wiki/SessionsAndTransactions#Transaction_demarcation_with_plain_JDBC "Sesje i transakcje"). Jestem pewien, że to był mój problem, zastąpiłem openSession() przez getCurrentSession() i zmieniono bity kodu.To działa teraz, ale! To nie jest doskonałe - dostaję nową sesję dla każdego żądania, ale to tylko projekt makiety , więc jest ok. Dzięki Steven! –

+2

Nowa sesja dla każdego zgłoszenia jest w rzeczywistości najlepszą praktyką. :) –

0

Ta zmiana ma miejsce, ponieważ Stara sesja nie została usunięta z ThreadLocal. Można to zrobić na dwa sposoby: - ​​ 1. Dodaj session.close() przed zakończeniem żądania. 2. Użyj klasy zarządzanej wiosną, aby obsłużyć widoki automatycznie.