Hi all,
my problem is with Session in View code. I had just added for long time hibernate sessions, but when application entries in the same SQL for three times in about ten seconds it give me an error at last SQL access, but in the other same SQL thar executes before, the error doesn´t exists.
What could be problem?. The error code is this:
Code:
[ INFO] {02/02/06 10:11:48} (bbdd.HttpListener.sessionCreated()) - Nueva Sesión: 918791DA23E88870E976EE8FF133CADD IP: 127.0.0.1
[ INFO] {02/02/06 10:11:48} (bbdd.Hibernate.ExtendedThreadLocalSessionContext.buildOrObtainSession()) - Opening a new Session
[ INFO] {02/02/06 10:11:48} (bbdd.Hibernate.ExtendedThreadLocalSessionContext.buildOrObtainSession()) - Disabling automatic flushing of the Session
[ERROR] {02/02/06 10:11:53} (bbdd.Hibernate.HibernateThreadFilter.doFilter()) - Cleanup after exception!
[ERROR] {02/02/06 10:11:53} (catalina.core.StandardWrapperValve.invoke()) - Servlet.service() para servlet default lanzó excepción
java.lang.NullPointerException
at bbdd.Hibernate.HibernateThreadFilter.doFilter(HibernateThreadFilter.java:137)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:362)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:738)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:526)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
[ INFO] {02/02/06 10:11:53} (bbdd.Hibernate.ExtendedThreadLocalSessionContext.buildOrObtainSession()) - Opening a new Session
[ INFO] {02/02/06 10:11:53} (bbdd.Hibernate.ExtendedThreadLocalSessionContext.buildOrObtainSession()) - Disabling automatic flushing of the Session
It use bind and unbind ok in the first two or three DB access, but after that it close sessionFactory and create another new.
HibernateThreadFilter.java Code:
/*
* HibernateThreadFilter.java
*
* Created on 11 de enero de 2006, 10:47
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
package bbdd.Hibernate;
import org.apache.commons.logging.*;
import org.hibernate.*;
import javax.servlet.*;
import javax.servlet.Filter;
import javax.servlet.http.*;
import java.io.IOException;
import bbdd.Hibernate.ExtendedThreadLocalSessionContext;
/**
* A servlet filter that provides a thread-bound session-per-request.
* <p>
* This filter should be used if your <tt>hibernate.current_session_context_class</tt>
* configuration is set to <tt>thread</tt> and you are not using JTA/CMT. You can use
* this filter for a thread-bound <tt>Session</tt>, either with resource-local transactions
* (direct JDBC) or user-managed JTA transactions. Set your
* <tt>hibernate.transaction.factory_class</tt> accordingly.
* <p>
* An alternative, more flexible solution is <tt>TransactionInterceptor</tt>
* that can be applied to any pointcut with JBoss AOP.
* <p>
* Note that you should not use this interceptor out-of-the-box with enabled optimistic
* concurrency control. Apply your own compensation logic for failed conversations, this
* is totally dependent on your applications design.
*
* @see org.hibernate.ce.auction.persistence.TransactionInterceptor
*
* @author christian@hibernate.org
*/
public class HibernateThreadFilter implements Filter {
private static Log log = LogFactory.getLog(HibernateThreadFilter.class);
private SessionFactory sf;
public static final String HIBERNATE_SESSION_KEY = "hibernate_session";
public static final String END_OF_CONVERSATION_FLAG = "end_of_conversation";
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
// Try to get a Hibernate Session from the HttpSession
HttpSession httpSession = ((HttpServletRequest) request).getSession();
Session hibernateSession = (Session) httpSession.getAttribute(HIBERNATE_SESSION_KEY);
try {
if (hibernateSession != null) {
log.debug("< Continuing conversation");
ExtendedThreadLocalSessionContext.bind(hibernateSession);
} else {
log.debug(">>> New conversation");
}
log.debug("Starting a database transaction");
sf.getCurrentSession().beginTransaction();
// Do the work...
chain.doFilter(request, response);
// End or continue the long-running conversation?
if (request.getAttribute(END_OF_CONVERSATION_FLAG) != null) {
log.debug("Flushing Session");
sf.getCurrentSession().flush();
log.debug("Committing the database transaction");
sf.getCurrentSession().getTransaction().commit();
log.debug("Closing and unbinding Session from thread");
sf.getCurrentSession().close(); // Unbind is automatic here
log.debug("Removing Session from HttpSession");
httpSession.setAttribute(HIBERNATE_SESSION_KEY, null);
log.debug("<<< End of conversation");
} else {
log.debug("Committing database transaction");
sf.getCurrentSession().getTransaction().commit();
log.debug("Unbinding Session from thread");
hibernateSession = ExtendedThreadLocalSessionContext.unbind(sf);
log.debug("Agregando sesion hibernate a la HttpSession");
httpSession.setAttribute("hibernate_session", hibernateSession);
log.debug("> Returning to user in conversation");
}
} catch (StaleObjectStateException staleEx) {
log.error("This interceptor does not implement optimistic concurrency control!");
log.error("Your application will not work until you add compensation actions!");
// Rollback, close everything, possibly compensate for any permanent changes
// during the conversation, and finally restart business conversation. Maybe
// give the user of the application a chance to merge some of his work with
// fresh data... what you do here depends on your applications design.
throw staleEx;
} catch (Throwable ex) {
// Rollback only
try {
if (sf.getCurrentSession().getTransaction().isActive()) {
log.debug("Trying to rollback database transaction after exception");
sf.getCurrentSession().getTransaction().rollback();
}
} catch (Throwable rbEx) {
log.error("Could not rollback transaction after exception!" + rbEx.getLocalizedMessage(), rbEx);
} finally {
log.error("Cleanup after exception!");
// Cleanup
log.debug("Closing and unbinding Session from thread");
sf.getCurrentSession().close(); // Unbind is automatic here
log.debug("Removing Session from HttpSession");
httpSession.setAttribute(HIBERNATE_SESSION_KEY, null);
}
if (ex.getCause().getLocalizedMessage()!= null) {
if (ex.getCause().getLocalizedMessage().indexOf("pool exhausted")!= -1) {
log.warn("El pool de conexiones de la aplicación está lleno.");
}
}
// Let others handle it... maybe another interceptor for exceptions?
throw new ServletException(ex);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
log.info("Initializing filter, obtaining Hibernate SessionFactory from HibernateUtil");
sf = oConexion.getSessionFactory();
}
public void destroy() {}
}
ExtendedThreadLocalSessionContext.javaCode:
/*
* ExtendedThreadLocalSessionContext.java
*
* Created on 17 de enero de 2006, 10:40
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
package bbdd.Hibernate;
import org.hibernate.context.*;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.classic.Session;
import org.hibernate.*;
import org.apache.commons.logging.*;
/**
*
* @author Administrador
*/
public class ExtendedThreadLocalSessionContext extends ThreadLocalSessionContext {
private static final Log log = LogFactory.getLog( ExtendedThreadLocalSessionContext.class );
public ExtendedThreadLocalSessionContext(SessionFactoryImplementor factory) {
super(factory);
}
// Always set FlushMode.NEVER on any Session
protected Session buildOrObtainSession() {
log.info("Opening a new Session");
Session s = super.buildOrObtainSession();
log.info("Disabling automatic flushing of the Session");
s.setFlushMode(FlushMode.NEVER);
return s;
}
// No automatic flushing of the Session at transaction commit, client calls flush()
protected boolean isAutoFlushEnabled() { return false; }
// No automatic closing of the Session at transaction commit, client calls close()
protected boolean isAutoCloseEnabled() { return false; }
// Don't unbind after transaction completion, we expect the client to do this
// so it can flush() and close() if needed (or continue the conversation).
protected CleanupSynch buildCleanupSynch() {
return new NoCleanupSynch(factory);
}
private static class NoCleanupSynch extends ThreadLocalSessionContext.CleanupSynch {
public NoCleanupSynch(SessionFactory factory) { super(factory); }
public void beforeCompletion() {}
public void afterCompletion(int i) {}
}
}
hibernate.cfg.xml Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">java:comp/env/jdbc/intranet</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<!-- Disable autocommit -->
<property name="connection.pool_size">1</property>
<property name="connection.autocommit">false</property>
<property name="transaction.auto_close_session">false</property>
<property name="transaction.flush_before_completion">false</property>
<!-- Disable second-level cache. -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="cache.use_query_cache">false</property>
<property name="cache.use_minimal_puts">false</property>
<property name="max_fetch_depth">3</property>
<!-- Print SQL to stdout. -->
<property name="show_sql">false</property>
<property name="format_sql">false</property>
<!-- Bind the getCurrentSession() method to the thread. -->
<property name="current_session_context_class">bbdd.Hibernate.ExtendedThreadLocalSessionContext</property>
<!-- Mapping files -->
<mapping resource="bbdd/hibernateXML/tTomcat_Config.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tAdjuntos.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tUsuarios.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tDPersonales.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tTickets.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tCentros.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tServidores.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tAvisos.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tIncidencias.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tEncuestas.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tEnc_Resultados.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tLineas_Datos.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tPerfiles.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tPermisos_Menu.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tMenu.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tPermisos_Menu_Info.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tMenu_Info.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tTip_Pago.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tDepartamentos.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tSistemas.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tCod_Inci.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tInci_Estados.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tTipo_Inci.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tTipos_Lineas.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tDpto_Tops.hbm.xml"/>
<mapping resource="bbdd/hibernateXML/tCorreos.hbm.xml"/>
</session-factory>
</hibernate-configuration>
oConexion.java (HibernateUtil) Code:
public class oConexion {
private static Log log = LogFactory.getLog(oConexion.class);
private static final String INTERCEPTOR_CLASS = "hibernate.util.interceptor_class";
private static Configuration configuration;
private static SessionFactory sessionFactory;
static {
// Create the initial SessionFactory from the default configuration files
try {
// Replace with Configuration() if you don't use annotations or JDK 5.0
configuration = new Configuration();
// This custom entity resolver supports entity placeholders in XML mapping files
// and tries to resolve them on the classpath as a resource
configuration.setEntityResolver(new ImportFromClasspathEntityResolver());
// Read not only hibernate.properties, but also hibernate.cfg.xml
configuration.configure();
// Set global interceptor from configuration
setInterceptor(configuration, null);
if (configuration.getProperty(Environment.SESSION_FACTORY_NAME) != null) {
// Let Hibernate bind the factory to JNDI
configuration.buildSessionFactory();
} else {
// or use static variable handling
sessionFactory = configuration.buildSessionFactory();
}
} 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 original Hibernate configuration.
*
* @return Configuration
*/
public static Configuration getConfiguration() {
return configuration;
}
/**
* Returns the global SessionFactory.
*
* @return SessionFactory
*/
public static SessionFactory getSessionFactory() {
SessionFactory sf = null;
String sfName = configuration.getProperty(Environment.SESSION_FACTORY_NAME);
if ( sfName != null) {
log.debug("Looking up SessionFactory in JNDI.");
try {
sf = (SessionFactory) new InitialContext().lookup(sfName);
} catch (NamingException ex) {
throw new RuntimeException(ex);
}
} else {
sf = sessionFactory;
}
if (sf == null)
throw new IllegalStateException("SessionFactory not available.");
return sf;
}
/**
* Closes the current SessionFactory and releases all resources.
* <p>
* The only other method that can be called on HibernateUtil
* after this one is rebuildSessionFactory(Configuration).
*/
public static void shutdown() {
log.info("Shutting down Hibernate.");
// Close caches and connection pools
getSessionFactory().close();
// Clear static variables
configuration = null;
sessionFactory = null;
}
/**
* Rebuild the SessionFactory with the static Configuration.
* <p>
* This method also closes the old SessionFactory before, if still open.
* Note that this method should only be used with static SessionFactory
* management, not with JNDI or any other external registry.
*/
public static void rebuildSessionFactory() {
log.debug("Using current Configuration for rebuild.");
rebuildSessionFactory(configuration);
}
/**
* Rebuild the SessionFactory with the given Hibernate Configuration.
* <p>
* HibernateUtil does not configure() the given Configuration object,
* it directly calls buildSessionFactory(). This method also closes
* the old SessionFactory before, if still open.
*
* @param cfg
*/
public static void rebuildSessionFactory(Configuration cfg) {
log.debug("Rebuilding the SessionFactory from given Configuration.");
synchronized(sessionFactory) {
if (sessionFactory != null && !sessionFactory.isClosed())
sessionFactory.close();
if (cfg.getProperty(Environment.SESSION_FACTORY_NAME) != null)
cfg.buildSessionFactory();
else
sessionFactory = cfg.buildSessionFactory();
configuration = cfg;
}
}
/**
* Register a Hibernate interceptor with the current SessionFactory.
* <p>
* Every Session opened is opened with this interceptor after
* registration. Has no effect if the current Session of the
* thread is already open, effective on next close()/getCurrentSession().
* <p>
* Attention: This method effectively restarts Hibernate. If you
* need an interceptor active on static startup of HibernateUtil, set
* the <tt>hibernateutil.interceptor</tt> system property to its
* fully qualified class name.
*/
public static SessionFactory registerInterceptorAndRebuild(Interceptor interceptor) {
log.debug("Setting new global Hibernate interceptor and restarting.");
setInterceptor(configuration, interceptor);
rebuildSessionFactory();
return getSessionFactory();
}
public static Interceptor getInterceptor() {
return configuration.getInterceptor();
}
/**
* Resets global interceptor to default state.
*/
public static void resetInterceptor() {
log.debug("Resetting global interceptor to configuration setting");
setInterceptor(configuration, null);
}
/**
* Either sets the given interceptor on the configuration or looks
* it up from configuration if null.
*/
private static void setInterceptor(Configuration configuration, Interceptor interceptor) {
String interceptorName = configuration.getProperty(INTERCEPTOR_CLASS);
if (interceptor == null && interceptorName != null) {
try {
Class interceptorClass =
oConexion.class.getClassLoader().loadClass(interceptorName);
interceptor = (Interceptor)interceptorClass.newInstance();
} catch (Exception ex) {
throw new RuntimeException("Could not configure interceptor: " + interceptorName, ex);
}
}
if (interceptor != null) {
configuration.setInterceptor(interceptor);
} else {
configuration.setInterceptor(EmptyInterceptor.INSTANCE);
}
}
}
Thanks all.