使用 Hibernate 和 Struts2,整个流程如下:
hibernate.cfg.xml
作为:
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.url">jdbc:oracle:thin:@xx.xx.xxx.xx:1521:TEST</property>
<property name="connection.username">xxxx</property>
<property name="connection.password">xxxxyyy</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<mapping class="test.models.administration.Menus" />
<mapping resource="Dual.hbm.xml" />
</session-factory>
</hibernate-configuration>
对于 DAO 的扩展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 类中扩展DAO之上,例如:
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";
}
}
如果我正在调用此abc
Action 类,通过重复单击指定的菜单链接,它会导致连接泄漏,计为打开的连接,我可以使用 jProfiler 看到,并且永远不会关闭。同时,它也在泄漏连接。
使用 jProfiler 的所有打开的泄漏连接的 StackTrace :
org.hibernate.transaction.JDBCTransaction.begin()
com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInter
ceptor.injectHibernateTransactionByAnnotation(java.lang.Object, org.hibernate.Session, boolean)
com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInter
ceptor.injectHibernateTransactionByAnnotation(java.lang.Object, org.hibernate.Session, boolean)
com.googlecode.s2hibernate.struts2.plugin.interceptors.SessionTransactionInjectorInter
ceptor.intercept(com.opensymphony.xwork2.ActionInvocation)
java.lang.Thread.run()
URL: /project/action-name
为什么 Hibernate 会泄露这些连接?
是不是这样,Hibernate 将连接保持在会话中并重用相同的连接,因此,如果我同时发出并发请求,如果会话连接被占用,它会泄漏连接。这只是我假设。我没有任何想法。