Hallo Forum
Ich habe seit längerem mit Hibernate Caching Problemen in einer JSF Applikation zu kämpfen. Es sieht so aus als würden manchmal Datenänderung erst verzögert in die Datenbank geschrieben d.h. nach einem Update navigiere ich auf eine andere Seite (mit redirect). Es wird mir der alte Zustand des Datensatzes angezeigt. (auch in der Datenbank ist die Änderung noch nicht ersichtlich. Erst nach einer erneute Navigation wird die Änderung in die DB geschrieben.
Ich habe schon diverses probiert. Ich nehme an es hängt irgendwie mit dem HibernateFilter zusammen. Vielleicht hat ja jemand bereits ähnlich Erfahrungen gemacht und hat mir einen Tipp.
Ich nutze fogldene Frameworks:
MyFaces 1.2.6
Facelets 1.1.14
richfaces 3.3.1
hibernate 3.3.1
HibernateFilter:
HibernateUtil:
Hibernate-CFG:
Viele Dank für irgendwelche Hinweise.
Grüsse
Alan
Ich habe seit längerem mit Hibernate Caching Problemen in einer JSF Applikation zu kämpfen. Es sieht so aus als würden manchmal Datenänderung erst verzögert in die Datenbank geschrieben d.h. nach einem Update navigiere ich auf eine andere Seite (mit redirect). Es wird mir der alte Zustand des Datensatzes angezeigt. (auch in der Datenbank ist die Änderung noch nicht ersichtlich. Erst nach einer erneute Navigation wird die Änderung in die DB geschrieben.
Ich habe schon diverses probiert. Ich nehme an es hängt irgendwie mit dem HibernateFilter zusammen. Vielleicht hat ja jemand bereits ähnlich Erfahrungen gemacht und hat mir einen Tipp.
Ich nutze fogldene Frameworks:
MyFaces 1.2.6
Facelets 1.1.14
richfaces 3.3.1
hibernate 3.3.1
HibernateFilter:
Code:
package com.xxx.groupware.hibernate;
import static com.xxx.groupware.hibernate.HibernateUtil.closeSession;
import static com.xxx.groupware.hibernate.HibernateUtil.commitTransaction;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.log4j.Logger;
/**
* A servlet filter that opens and closes a Hibernate Session for each request.
* <p>
* This filter guarantees a sane state, committing any pending database
* transaction once all other filters (and servlets) have executed. It also
* guarantees that the Hibernate <tt>Session</tt> of the current thread will
* be closed before the response is send to the client.
* <p>
* Use this filter for the <b>session-per-request</b> pattern and if you are
* using <i>Detached Objects</i>.
*
* @see HibernateUtil
* @author Christian Bauer <christian@hibernate.org>
*/
public class HibernateFilter implements Filter {
private static Logger log = Logger.getLogger(HibernateFilter.class);
public void init(FilterConfig filterConfig) throws ServletException {
log.info("Servlet filter init, now opening/closing a Session for each request.");
}
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
try {
// We don't start the database transaction here, but when first needed
chain.doFilter(request, response);
// Commit any pending database transaction.
commitTransaction();
} finally {
// No matter what happens, close the Session.
closeSession();
}
}
public void destroy() {}
}
HibernateUtil:
Code:
package com.xxx.groupware.hibernate;
import org.apache.log4j.Logger;
import org.hibernate.CacheMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
/**
* Basic Hibernate helper class, handles SessionFactory, Session and Transaction.
* <p>
* Uses a static initializer for the initial SessionFactory creation
* and holds Session and Transactions in thread local variables.
*
* @author christian@hibernate.org
*/
public class HibernateUtil {
private static Logger log = Logger.getLogger(HibernateUtil.class);
private static Configuration configuration;
private static SessionFactory sessionFactory;
private static final ThreadLocal threadSession = new ThreadLocal();
private static final ThreadLocal threadTransaction = new ThreadLocal();
// Create the initial SessionFactory from the default configuration files
static {
try {
log.info("Start building Session Factory..");
configuration = new Configuration();
sessionFactory = configuration.configure().buildSessionFactory();
// We could also let Hibernate bind it to JNDI:
// configuration.configure().buildSessionFactory()
log.info("Building Session Factory succeeded..");
} catch (Throwable ex) {
// We have to catch Throwable, otherwise we will miss
// NoClassDefFoundError and other subclasses of Error
log.error("Building SessionFactory failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
* Returns the SessionFactory used for this static class.
*
* @return SessionFactory
*/
public static SessionFactory getSessionFactory() {
/* Instead of a static variable, use JNDI:
SessionFactory sessions = null;
try {
log.info("Start building Session Factory..");
configuration = new Configuration();
sessionFactory = configuration.configure().buildSessionFactory();
log.info("Building Session Factory succeeded..");
} catch (Throwable ex) {
log.error("Building SessionFactory failed.", ex);
throw new ExceptionInInitializerError(ex);
}
return sessions;
*/
return sessionFactory;
}
/**
* Retrieves the current Session local to the thread.
* <p/>
* If no Session is open, opens a new Session for the running thread.
*
* @return Session
*/
public static Session getSession() {
// With CMT, this should return getSessionFactory().getCurrentSession() and do nothing else
Session s = (Session) threadSession.get();
//System.out.println("***DEBUG - session init - session: "+s);
if (s!=null){
//System.out.println("***DEBUG - session init - session: open? "+s.isOpen());
s.isOpen();
}
// added isOpen to condition to make it possible to close a session for detached objects...
if (s == null || !s.isOpen()) {
log.debug("Opening new Session for this thread.");
SessionFactory sFactory = getSessionFactory();
//System.out.println("***DEBUG - session init - session null! try get factory: "+sFactory);
if (sFactory==null){
log.error("Building SessionFactory failed.");
}
else
{
s=sFactory.openSession();
//System.out.println("***DEBUG - session init - session after getting factory: open? "+s.isOpen());
}
threadSession.set(s);
}
//s.setCacheMode(CacheMode.REFRESH);
return s;
}
/**
* Closes the Session local to the thread.
*/
public static void closeSession() {
// Would be written as a no-op in an EJB container with CMT
Session s = (Session) threadSession.get();
threadSession.set(null);
if (s != null && s.isOpen()) {
log.debug("Closing Session of this thread.");
s.flush();
s.close();
System.out.println("Session has been flushed and closed...");
}
}
/**
* Start a new database transaction.
*/
public static void beginTransaction() {
// Would be written as a no-op in an EJB container with CMT
Transaction tx = (Transaction) threadTransaction.get();
if (tx == null) {
log.debug("Starting new database transaction in this thread.");
tx = getSession().beginTransaction();
threadTransaction.set(tx);
}
}
/**
* Commit the database transaction.
*/
public static void commitTransaction() {
// Would be written as a no-op in an EJB container with CMT
Transaction tx = (Transaction) threadTransaction.get();
try {
if ( tx != null && !tx.wasCommitted()
&& !tx.wasRolledBack() ) {
log.debug("Committing database transaction of this thread.");
tx.commit();
}
//threadTransaction.set(null);
} catch (HibernateException ex) {
rollbackTransaction();
throw ex;
}
}
/**
* Rollback the database transaction.
*/
public static void rollbackTransaction() {
// Would be written as a no-op in an EJB container with CMT (maybe setRollBackOnly...)
Transaction tx = (Transaction) threadTransaction.get();
try {
threadTransaction.set(null);
if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
log.debug("Tyring to rollback database transaction of this thread.");
tx.rollback();
}
} finally {
closeSession();
}
}
}
Hibernate-CFG:
Code:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.autocommit">true</property>
<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="hibernate.connection.password">xxxxxx</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/timerep</property>
<property name="hibernate.connection.username">xxxx</property>
<property name="hibernate.default_catalog">timerep</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.autoReconnect">true</property>
<mapping ......
</session-factory>
</hibernate-configuration>
Viele Dank für irgendwelche Hinweise.
Grüsse
Alan
Zuletzt bearbeitet: