在Swing应用程序中使用Hibernate进行会话管理

如何在Java桌面Swing应用程序中进行Hibernate会话管理? 你使用一次会话吗? 多个会话?

以下是有关该主题的一些参考文献:

  • http://www.hibernate.org/333.html
  • http://blog.schauderhaft.de/2008/09/28/hibernate-sessions-in-two-tier-rich-client-applications/
  • http://in.relation.to/Bloggers/HibernateAndSwingDemoApp

单次会话。 当您需要执行一组操作(如对话框OK按钮后更新数据)时启动事务,最后提交tx。 虽然连接是连续打开的(因为它是相同的会话),因此Hib和RDBMS都可以使用所有缓存机会。

在连接失效的情况下实现透明会话重新打开也是一个好主意 – 用户倾向于长时间保持应用程序打开,即使周末重新启动数据库服务器,它也应该在周一继续工作。

更新

Jens Schauder提供了使用多个会话的原因:会话的部分(不需要的)更新。 那么,这取决于你使用Hibernate的方式。

假设我们打开了两个对话框(如Jens的博客示例中所示)。 如果用户点击radiobox,我们立即更新与此radiobox关联的Hibernate实体,那么,当用户单击Cancel时,我们遇到了麻烦 – 会话已经更新。

正如我所看到的,正确的方法是仅更新对话框变量(非Hibernate对象)。 然后,当用户单击OK时,我们开始一个事务,合并更新的对象,提交事务。 没有垃圾被保存到会话中。

MyHibernateUtils.begin(); Settings settings = DaoSettings.load(); // update setttings here DaoSettings.save(settings); MyHibernateUtils.commit(); 

如果我们实现这种干净的关注分离,我们稍后可以通过简单更改MyHibernateUtils.begin()实现来切换到多个会话。

至于可能的内存泄漏,那么…… Transaction.commit()调用Session.flush(),AFAIK也清理缓存。 此外,可以通过调用Session.setCacheMode()手动控制缓存策略。

每个线程“”’会话’的问题”很好Swing应用程序在EDT之外进行数据库访问,通常是在新创建的SwingWorker线程中。 这样,“每个线程的”’会话”很快变成”’每次点击会话””。

不要使用单个会话。 对于除最小应用程序之外的所有应用程序,它将增长,收集过时的数据并变得越来越慢,因为脏检查需要检查会话中的每个实体。

如果您不需要/希望延迟加载和跟踪Hibernate的更改,您可以使用短期会话。

但如果您想从Hibernate的强大function中受益,请使用我在博客中描述的方法: http : //blog.schauderhaft.de/2008/09/28/hibernate-sessions-in-two-tier-rich-client-应用程序/

或者在德文版中:

http://blog.schauderhaft.de/2007/12/17/hibernate-sessions-in-fat-client-anwendungen/

AFAIK它实际上与http://in.relation.to/Bloggers/HibernateAndSwingDemoApp中描述的方法相同,但建议如何实际调整会话范围:On Session per Frame,除了使用会话的模式帧父框架。

只需确保永远不要组合来自不同会话的对象。 这会造成很多麻烦。

回复Vladimirs更新:

  • 取消实际上对我的方法非常好:抛弃会话。
  • 当您使用应用程序的单个会话时,session.flush不能解决日益增长的会话问题。 当然,通过这种方法,您可以描述您可以使用应该正常工作的短期会话。 但
  • 你输了很多:延迟加载只适用于附加对象,自动检测脏对象。 如果您使用分离的对象(或根本不是实体的对象),您必须自己执行此操作。

每个线程( doc )和版本或时间戳列使用一个会话以允许乐观并发,从而避免会话到实例冲突。 除非您需要长时间运行的事务或限制性隔离级别,否则在需要时将实例附加到会话。