Estou com problemas de sessão em minha aplicação que de forma indeterminada acaba pegando uma sessão fechada. Esse problema só acontece em produção mesmo fazendo os ‘devidos’ tratamentos na aplicação.
Vejam e me respondam onde possívelmente estou errando.
Estou usando Hibernate 3.2.2 e Spring 2.5 e pool de conexões DBCP.
Meu componente que tem o sessionFactory injeta e libera as sessions p/ outros componentes via o seu singleton:
public class HibernateFactory implements Serializable {
private static final long serialVersionUID = 5678530444200888063L;
private SessionFactory sessionFactory;
private static HibernateFactory instance;
private Session session;
public HibernateFactory() {
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
}
public Session getSession(){
//session =sessionFactory.getCurrentSession();
if(session == null || !session.isOpen()){
session = sessionFactory.openSession();
}
return session;
}
public static HibernateFactory getInstance(){
if(instance == null)
instance = new HibernateFactory();
return instance;
}
...
Se eu descomentar a linha do getCurrentSession() pego a seguinte exception:
org.hibernate.HibernateException: createCriteria is not valid without active transaction
Nos métodos que não alteram dados na base, eu não abro transação e ponho @Transaction(readonly=true), nos demais abro e fecho transações normalmente.
Abaixo segue minhas configurações que possam estar relacionadas ao problema:
web.xml
....
<listener>
<listener-class> org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
....
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
applicationContext.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/BANCO?autoReconnect=true"/>
<property name="username" value="USUARIO"/>
<property name="password" value="SENHA"/>
<property name="initialSize">
<value>20</value>
</property>
<property name="maxActive">
<value>50</value>
</property>
<property name="maxWait">
<value>20000</value>
</property>
<property name="maxIdle">
<value>10</value>
</property>
<property name="minIdle">
<value>2</value>
</property>
<property name="removeAbandoned">
<value>true</value>
</property>
<property name="removeAbandonedTimeout">
<value>100</value>
</property>
<property name="validationQuery">
<value>select 1</value>
</property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Hibernate transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
.....
hibernate.cfg.xml
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.pool_size">30</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_structured_entries">true</property>
<property name="hibernate.max_fetch_depth">2</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
ehcache.xml
<ehcache>
<diskStore path="java.io.tmpdir" />
<defaultCache
maxElementsInMemory="200"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false" />
<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="500"
eternal="false"
timeToIdleSeconds="200"
timeToLiveSeconds="500"
overflowToDisk="true"/>
<cache name ="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory ="250"
eternal ="true"
overflowToDisk ="true"/>
<cache name="MINHACLASSE1"
maxElementsInMemory="30"
eternal="false"
timeToIdleSeconds="10000"
timeToLiveSeconds="10000"
overflowToDisk="false" />
<cache name="MINHACLASSE2"
maxElementsInMemory="30"
eternal="false"
timeToIdleSeconds="10000"
timeToLiveSeconds="10000"
overflowToDisk="false" />
</ehcache>