EntityManager lifecycle and persistent client-server-communication
我们正在开发(JavaSE-)应用程序,该应用程序通过持久的tcp连接与许多客户端进行通信。客户端连接,执行一些/许多操作(已更新为SQL数据库)并关闭应用程序/与服务器断开连接。我们正在使用Hibernate-JPA,并使用ThreadLocal-variable自行管理EntityManager-lifecycle。实际上,到目前为止,我们在每个客户端请求上都创建了一个新的EntityManager-instance。最近,我们进行了一些分析,发现hibernate在每个UPDATE语句之前对数据库执行SELECT查询。那是因为我们的实体处于分离状态,并且每个新的EntityManager都会首先将该实体附加到持久性上下文。当服务器处于负载状态时,这会导致大量的SQL开销(因为我们有一个写繁重的应用程序),并且我们试图消除这种泄漏。
- 首先,我们考虑了二级缓存。但是,我们发现,每当添加或删除新项目时,hibernate会使它的查询缓存和集合缓存失效。
- 再次考虑,只要客户端在服务器上登录,我们就评估是否保持EntityManager正常运行。但是我不知道这是否是"最佳实践",因为存在一些缺点:线程安全,EntityManager实例的管理开销等。
简而言之:我们正在寻找一种在每次UPDATE之前摆脱那些SELECT语句的方法。有什么想法吗?
重新连接分离的实体时摆脱
在JPA 2.0中,您可以按以下方式访问特定于Hibernate的操作:
1 | em.unwrap(Session.class).update(o); |
另请参见:
- 11.6。修改分离的对象
一个可能的选择是对更新语句使用StatelessSession。我已经在"大量写入"应用程序中成功使用了它。