I am using struts2-fullhibernatecore-plugin-2.2.1-GA.jar for injecting session as,
@SessionTarget
protected Session hSession;
@TransactionTarget
protected Transaction hTransaction;
i can see in jboss logs stacktraces that it's leaving the jdbc connections open (as unclosed). Stacktrace as:
[org.jboss.jca.core.api.connectionmanager.ccm.CachedConnectionManager]
(http-- 0.0.0.0-8080-203) IJ000100: Closing a connection for you.
Please close them yourself: org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@62a8c68c:
java.lang.Throwable: STACKTRACE
at org.jboss.jca.core.connectionmanager.ccm.CachedConnectionManagerImpl.registerConnection(CachedConnectionManagerImpl.java:265)
at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:495)
at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:129)
at org.hibernate.connection.DatasourceConnectionProvider.getConnection(DatasourceConnectionProvider.java:92) [hibernate3.jar:]
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446) [hibernate3.jar:]
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167) [hibernate3.jar:]
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:142) [hibernate3.jar:]
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:85) [hibernate3.jar:]
at com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInterceptor.injectHibernateTransactionByAnnotation(SessionTransactionInjectorInterceptor.java:572) [struts2-fullhibernatecore-plugin-2.2.1-GA.jar:]
at com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInterceptor.injectHibernateTransactionByAnnotation(SessionTransactionInjectorInterceptor.java:579) [struts2-fullhibernatecore-plugin-2.2.1-GA.jar:]
at com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInterceptor.intercept(SessionTransactionInjectorInterceptor.java:190) [struts2-fullhibernatecore-plugin-2.2.1-GA.jar:]
Coding Part, The way i am doing the things are as: Using AbstractSimpleGenericDao class:
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.googlecode.s2hibernate.struts2.plugin.annotations.SessionTarget;
import com.googlecode.s2hibernate.struts2.plugin.annotations.TransactionTarget;
@SuppressWarnings("unchecked")
public abstract class AbstractSimpleGenericDao<C, I extends Serializable> {
Class<C> entityClass;
@SessionTarget
protected Session hSession;
@TransactionTarget
protected Transaction hTransaction;
{
entityClass = (Class<C>) ((ParameterizedType)
getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public List<C> getAll()
{
try
{
return hSession.createCriteria(entityClass).list();
}
catch (HibernateException e)
{
throw e;
}
}
public C get(I id)
{
try
{
return (C) hSession.get(entityClass, id);
}
catch (HibernateException e)
{
throw e;
}
}
public void save(C object)
{
try
{
hSession.save(object);
}
catch (HibernateException e)
{
hTransaction.rollback();
throw e;
}
}
public void update(C object)
{
try
{
hSession.update(object);
}
catch (HibernateException e)
{
hTransaction.rollback();
throw e;
}
}
public void delete(I id)
{
try
{
C actual = get(id);
hSession.delete(actual);
}
catch (HibernateException e)
{
hTransaction.rollback();
throw e;
}
}
}
Then extending above AbstractSimpleGenericDao class in my DAO class as:
public class UserRoleDAO extends AbstractSimpleGenericDao<UserRole, UserRoleId> {
public List L() {
try {
String queryString = "from UserRole";
Query queryObject = hSession.createQuery(queryString);
return queryObject.list();
} catch (RuntimeException re) {
throw re;
}
}
Then in my struts Action class, instantiating DAO and retrieving list as:
public class abc extends ActionSupport{
private UserRoleDAO userRoleDao = new UserRoleDAO();
private List ls=new ArrayList();
public String execute()
{
List ls=userRoleDao.L()
return "success";
}
}
Above all, I am using struts2 custom Interceptor for Authentication, and as interceptors are not thread safe. After ActionInvocation invoke()
method in interceptor, getting the above error stacktrace.
Does that mean interceptor, being not thread safe, could leak the hibernate session (Connections)?