Erro estranho na Sessão do Hibernate, na segunda requisição

Pessoal

Tenho uma aplicação que usa Hibernate e JPA.

Quando eu inicializo a aplicação, tudo funciona corretamente. Porém, se após carregar a tela, eu tenho recarregar (simplesmente atualizar a página, apertando F5), dá o seguinte erro:

Se após este erro, eu atualizo novamente a página, tudo funciona denovo, mas se eu atualizar novamente, após funcionar, novamente ocorre este erro.

Estranhamente, após carregar a aplicação pela primeira vez, a cada vez que recarrego a página, ocorre o inverso do que havia ocorrido na vez anterior (quando tudo funciona, na próxima vez dará erro… quando dá erro, na próxima vez funciona). Deu pra entender o problema?

Caso ajude, aqui estão alguns dos meus códigos:

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
	<persistence-unit name="SCPDEJB" transaction-type="JTA">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<jta-data-source>jdbc/scpdDS</jta-data-source>
		<properties/>
	</persistence-unit>
</persistence>

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory name="hibernate/sessionFactory">
		<property name="connection.datasource">jdbc/scpdDS</property>
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
		<property name="connection.isolation">2</property>
		<property name="show_sql">true</property>
		<property name="format_sql">true</property>
		<property name="use_sql_comments">true</property>
		<property name="jdbc.batch_size">0</property>
		<property name="jdbc.batch_versioned_data">true</property>
		<property name="max_fetch_depth">3</property>
		<property name="jdbc.fetch_size">25</property>
		<property name="default_batch_fetch_size">8</property>
		<property name="default_entity_mode">pojo</property>
		<property name="order_updates">true</property>
		<property name="generate_statistics">false</property>
		<property name="jdbc.use_streams_for_binary">true</property>
		<property name="connection.release_mode">auto</property>
		<property name="transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
		<property name="transaction.manager_lookup_class">org.hibernate.transaction.SunONETransactionManagerLookup</property>
		<property name="transaction.auto_close_session">true</property>
		<property name="transaction.flush_before_completion">true</property>
		<property name="current_session_context_class">jta</property>
		<property name="connection.aggressive_release">true</property>
		<property name="cache.use_query_cache">false</property>
		<property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

		<mapping class="entities.Perfil" />
		<mapping class="entities.Usuario" />
		<mapping class="entities.Disciplina" />

	</session-factory>
</hibernate-configuration>

HibernateUtil.java

package util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static SessionFactory sessionFactory;
    
    @SuppressWarnings("unchecked")
	public static final ThreadLocal session = new ThreadLocal();

    static {
        try {
            Configuration config = new AnnotationConfiguration();
            sessionFactory = config.configure().buildSessionFactory();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unchecked")
	public static Session currentSession() {
        Session s = (Session) session.get();
        // Open a new Session, if this Thread has none yet
        if (s == null) {
            s = sessionFactory.openSession();
            session.set(s);
        }
        return s;
    }

    @SuppressWarnings("unchecked")
	public static void closeSession() {
        Session s = (Session) session.get();
        if (s != null) {
            s.close();
        }
        session.set(null);
    }

    public static Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

GenericHibernateDAO.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dao.hibernate;

import util.*;
import dao.GenericDAO;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;

public abstract class GenericHibernateDAO<T, ID extends Serializable>
        implements GenericDAO<T, ID> {

    private Class<T> persistentClass;
    private Session session;

    @SuppressWarnings("unchecked")
	public GenericHibernateDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
     }

    public void setSession(Session s) {
        this.session = s;
    }

    protected Session getSession() {
        if (session == null)
            session = HibernateUtil.getCurrentSession();
        return session;
    }

    public Class<T> getPersistentClass() {
        return persistentClass;
    }

    @SuppressWarnings("unchecked")
	public T findById(ID id) {
        T entity = (T) getSession().get(getPersistentClass(), id);

        return entity;
    }

    public List<T> findAll() {
        return findByCriteria();
    }

    @SuppressWarnings("unchecked")
	public List<T> findByExample(T exampleInstance) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        Example example =  Example.create(exampleInstance);
        crit.add(example);
        return crit.list();
    }

    public T save(T entity) {
        getSession().saveOrUpdate(entity);
        return entity;
    }

    public T saveOrUpdate(T entity) {
        getSession().saveOrUpdate(entity);
        return entity;
    }

    public T update(T entity) {
        getSession().update(entity);
        return entity;
    }

    public void delete(T entity) {
        getSession().delete(entity);
    }

    public void deleteById(ID id) {
        T entity = this.findById(id);
        this.delete(entity);
    }

    public void flush() {
        getSession().flush();
    }

    public void clear() {
        getSession().clear();
    }

    @SuppressWarnings("unchecked")
	protected List<T> findByCriteria(Criterion... criterion) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        for (Criterion c : criterion) {
            crit.add(c);
        }
        return crit.list();
   }    

}

Qualquer ajuda é bem vinda!

Obrigado!

O erro diz tudo:

Ou seja, sua Session está fechada.
Em alguma parte do seu código você está tentando utilizar a Session que está fechada.

A forma mais simples de achar esse problema é debugar o código, inserir break-point, e investigar passo a passo. Aconselho iniciar pelo método que carrega a página.

Uma observação: ou você usa JPA ou hibernate.xml.

Noto que você está usando hibernate.cfg.xml, além de uma HibernateUtils. Ou seja, você assim usa o hibernate crú. Porém você possui um persistence.xml. Sendo assim você tem uma session de JPA e uma manual do Hibernate.

Use ou uma ou outra.