【发布时间】:2014-01-29 15:18:45
【问题描述】:
我已经使用 Spring MVC + Hibernate 开发了一个 Web 应用程序,并且在运行负载测试时,它似乎过于频繁地调用垃圾收集器。恐怕这可能与我管理 Hibernates 会话的方式有关。
我有一个 AbstractDao,我的所有 DAO 对象都扩展了它:
public class AbstractDaoHibernateImpl {
protected GenericDataBaseExceptionHandler exceptionHandler;
private SessionFactory sessionFactory;
public AbstractDaoHibernateImpl() {
}
public void setExceptionHandler(GenericDataBaseExceptionHandler exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
}
在 spring 实体 bean 配置中,我这样定义每个 DAO:
<bean name="userDao" class="com.kelmer.dao.UserDaoImpl">
<property name="sessionFactory" ref="SessionFactory" />
<property name="exceptionHandler" ref="defaultSpringExceptionHandler" />
</bean>
然后这是来自我的一个 DAO 的示例方法:
@Override
public EstacionVO findById(Long id) throws InstanceNotFoundException {
User e = (User ) getSession().createQuery(SELECT_USER_BY_ID).setParameter("userId", id).uniqueResult();
if (e == null) {
throw new InstanceNotFoundException ("No user with provided Id", User.class);
}
return e;
}
老实说,我可以看到任何可能导致内存泄漏的东西,但我又不是真正的专家。我在做会话管理吗?我知道我从一些遗留代码中获取了来自 AbstractDao 的代码,我担心这可能是内存问题所在,因为没有明确的会话关闭或终结。
附言。对于事务管理,我在 Spring 上下文中使用 <tx:annotation-driven />,并使用 @Transactional 注释每个方法。
【问题讨论】:
-
我会使用
Session.load(class, PrimaryKey)通过其主键加载对象,而不是使用查询。 -
这只是一个示例查询,并非真实案例场景
-
也许你应该在提问时发布真实的代码。
-
也许我只是想说明我执行查询的方式,而不是查询本身。问题存在于整个应用程序中,所以我的猜测是它与任何特定查询无关。
-
如果您使用的是 Spring 并且您有适当的 tx 管理设置,则应在事务完成后关闭会话。如果您没有正确的 tx 或 spring 的错误 tx 集成,您可能会泄漏会话。但是,如果没有您的实际 tx 配置和/或 spring 设置,这很难确定。
标签: java spring hibernate spring-mvc garbage-collection