我正在使用struts2-fullhibernatecore-plugin-2.2.1-GA.jar来注入会话,
@SessionTarget
protected Session hSession;
@TransactionTarget
protected Transaction hTransaction;
我可以在jboss logs stacktraces中看到它让jdbc连接保持打开状态(如未关闭)。 Stacktrace为:
[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:]
编码部分,我做事情的方式如下: 使用 AbstractSimpleGenericDao 类:
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;
}
}
}
然后在我的DAO类中扩展 AbstractSimpleGenericDao类:
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;
}
}
然后在我的struts Action类中,实例化DAO并将列表检索为:
public class abc extends ActionSupport{
private UserRoleDAO userRoleDao = new UserRoleDAO();
private List ls=new ArrayList();
public String execute()
{
List ls=userRoleDao.L()
return "success";
}
}
最重要的是,我使用struts2自定义拦截器进行身份验证,并且拦截器不是线程安全的。在拦截器中ActionInvocation invoke()
方法之后,得到上面的错误堆栈跟踪。
这是否意味着拦截器,不是线程安全的,可以泄漏休眠会话(连接)?