假设我有以下内容:
public class DAOFactory {
@Inject private final SessionFactory factory;
private final ThreadLocal<Session> session = new ThreadLocal<>();
// In a nutshell: create an AbstractDAO associated with the session object held by the ThreadLocal above
public <T> AbstractDAO<T> createObject(Class<T> objectClass) { ... }
}
我遇到的问题是需要关闭这些会话,只有从createObject()
创建DAO的线程才能这样做。显然,AbstractDAO
不能有一个紧密的例程,因为相同的Session
可以与多个AbstractDAO
对象相关联,因此DAOFactory
必须承担关闭会话的负担。仍然存在悬空Session
的风险:如果创建AbstractDAO
的主题不再存在,关联的Session
如何关闭?
我的一种方法是使用如下清理方法:
public class DAOFactory {
// createObject() uses Thread.getCurrentThread.getId() and sessionMap.computeIfAbsent()
private final ConcurrentMap<Long, Session> sessionMap = new ConcurrentHashMap<>();
public void cleanup() {
for (Session session : sessionMap.values()) {
session.close();
}
sessionMap.clear();
}
}
问题是“这种方法有多安全”,“这是一个好主意”,“应该这样做”吗?如果没有,有什么好的选择?
请注意,DAOFactory
主要是在考虑某种测试情况的情况下创建的:一个线程启动测试运行并创建一个DAOFactory
,它可能会产生其他使用它的线程。创建DAOFactory
的线程将始终比它产生的任何线程更长,并且将始终是在测试结束时调用cleanup()
的线程。
答案 0 :(得分:0)
手动会话管理不是一个好主意。 Hibernate已经提供了一个SPI,所以你不必自己做。
我建议你开始使用Spring事务管理,它也提供自动会话管理。