Java EntityManager生命周期和持久客户机-服务器通信
我们正在开发一个(JavaSE-)应用程序,它通过持久tcp连接与许多客户机通信。客户端连接、执行一些/许多操作(更新为SQL数据库)并关闭应用程序/断开与服务器的连接。我们正在使用Hibernate JPA,并使用ThreadLocal变量自行管理EntityManager生命周期。实际上,我们在每个客户机请求上创建了一个新的EntityManager实例,到目前为止效果良好。最近我们分析了一下,发现hibernate在每个UPDATE语句之前都会对DB执行SELECT查询。这是因为我们的实体处于分离状态,每个新的EntityManager首先将实体附加到持久性上下文。当服务器负载不足时(因为我们有一个写操作繁重的应用程序),这会导致巨大的SQL开销,我们试图消除这种泄漏Java EntityManager生命周期和持久客户机-服务器通信,java,hibernate,jpa,entitymanager,Java,Hibernate,Jpa,Entitymanager,我们正在开发一个(JavaSE-)应用程序,它通过持久tcp连接与许多客户机通信。客户端连接、执行一些/许多操作(更新为SQL数据库)并关闭应用程序/断开与服务器的连接。我们正在使用Hibernate JPA,并使用ThreadLocal变量自行管理EntityManager生命周期。实际上,我们在每个客户机请求上创建了一个新的EntityManager实例,到目前为止效果良好。最近我们分析了一下,发现hibernate在每个UPDATE语句之前都会对DB执行SELECT查询。这是因为我们的实体
- 首先,我们考虑了二级缓存。然而,我们发现,每当添加或删除新项时,hibernate就会使其查询和集合缓存失效李>
- 再想一想,我们评估是否在客户端登录到服务器时保持EntityManager处于运行状态。但我想知道这是否是一种“最佳实践”,因为它有一些缺点:线程安全,管理EntityManager实例的开销,等等
简而言之:我们正在寻找一种方法,在每次更新之前去掉那些SELECT语句。有什么想法吗?一个可能的选择是使用update语句。我已经在我的“写重”应用程序中成功地使用了它。在重新附加分离的实体时,摆脱
select
语句的一种可能方法是使用特定于Hibernate的update()
操作,而不是merge()
update()
无条件运行update
SQL语句,并使分离的对象持久化。如果会话中已存在具有相同标识符的持久对象,则会引发异常。因此,如果您确信:
em.unwrap(Session.class).update(o);
另请参见: