2011-06-22 26 views
5

Estoy usando Struts 2 e Hibernate. Tengo una tabla simple con un campo de Fecha que almacena información sobre cuándo tuvo lugar una determinada acción. Este valor de fecha se muestra en mi jsp. El problema que tengo es que después de que el hibernate actualiza el db, la página jsp no actualiza el valor de la fecha. Como un ejemplo de trabajo:¿Almacenamiento en caché de Hibernate?

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

Cuando actualizar manualmente (F5), entonces está bien - el valor cambia la fecha de date1 a date2 (es decir 15:00-16:00). Pero si continúo actualizando, entonces el jsp mostrará una vez date1 y next time date2, y así sucesivamente. Tengo el siguiente en mi hibernate.cfg:

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

Experimenté con desalojar de Hibernate(), flush(). He intentado añadir un scriptlet (sí, lo sé - scriptles son una mala práctica):

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

estoy un poco atascado aquí - cualquier ayuda apreciada.

Gracias, Damo

EDIT: que tienen una clase DaoEngine, que se extienden a todos mis DAOs.

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

¿Qué mecanismo está utilizando para administrar y limpiar sus sesiones de Hibernate (o administradores de entidades JPA)? –

Respuesta

4

Pero si sigo refrescante, entonces el JSP vez mostrará la fecha 2 fecha1 y próxima vez y así sucesivamente.

Supongo que quiere decir que a medida que actualiza, la salida está cambiando entre datos antiguos y nuevos?

Si es así, esto generalmente se debe a un error al cerrar y eliminar la sesión de Hibernate de su ThreadLocal. La mayoría de los servidores de aplicaciones reutilizarán los subprocesos de un grupo de subprocesos para procesar las solicitudes, por lo que si una sesión anterior no se elimina de ThreadLocal, se reutilizará y su contexto de persistencia no estará sincronizado con la base de datos.

Esté absolutamente seguro de que está llamando al método close() en su clase DaoEngine antes de que finalice la solicitud. Probablemente debas configurar y eliminar sesiones en un filtro de servlet o un interceptor Struts2.

+0

Seguí su consejo, leí un poco y resulta que seesionFactory.openSession() no es una gran idea. Si lo usa, debe proporcionar el código para administrar la sesión (como se explica aquí: [Sesiones y transacciones] (http://community.jboss.org/wiki/SessionsAndTransactions#Transaction_demarcation_with_plain_JDBC "Sesiones y transacciones"). Estoy estoy seguro de que ese era mi problema. Reemplacé openSession() con getCurrentSession() y cambié bits de código. Funciona ahora. Pero no es perfecto, recibo una nueva sesión para cada solicitud, pero esto es solo un proyecto de simulación , así que está bien. Gracias Steven! –

+2

Una nueva sesión para cada solicitud es en realidad una mejor práctica. :) –

0

Este cambio está sucediendo ya que la sesión anterior no se elimina de ThreadLocal. Esto se puede hacer de 2 maneras: 1. Agregue session.close() antes de finalizar la solicitud. 2. Utilice la clase administrada de primavera para manejar la misión automáticamente.

Cuestiones relacionadas