何时使用EntityManager.clear()?

Kev*_*ith 31 orm hibernate

自定义JPA映射器类有一个方法:

removeUser()

1. execute 'DELETE' HQL query to remove user
2. call getEntityManager().flush();
3. call getEntityManager().clear();
Run Code Online (Sandbox Code Playgroud)

如果我正确理解clear(),它将从上下文中删除所有持久性实体.-资源

不过,我也在这里读到,

you should define clear architecture- and design guidelines about where a 
clear() can be called. 
Run Code Online (Sandbox Code Playgroud)

什么是何时调用clear()的明确指南?

JB *_*zet 38

文章解释了它.清除实体管理器会清空其关联的缓存,从而强制在事务中稍后执行新的数据库查询.在使用事务绑定实体管理器时,几乎从不需要清除实体管理器.我认为有两个原因要明确:

  • 在进行批处理时,为了避免巨大缓存占用内存并因长时间脏检查而增加刷新时间
  • 当您进行DML或SQL查询时,它完全绕过实体管理器缓存(如您的示例中所示).在这种情况下,由于查询,缓存所保持的状态不会反映数据库中的内容,因此您要清除缓存以避免此不一致.

  • 在 Spring Boot 批处理中使用 entityManager.clear() 和 Spring Data JPA 处理时间从超过 3 小时到不到 10 分钟! (2认同)

Sim*_*lov 5

是的,它完全取决于平台的架构风格作为文档点.

  • 例如,如果在您的应用程序中EM是线程关联的,那么事务管理的一个解决方案是实现Session-Per-Request模式,该模式在用户请求的每个开始时启动事务并在请求的每一端提交并清除缓存为了防止脏读.这只是一个简单的例子
  • 其他示例在SOA平台中.对于每个服务,也可以在开始时打开一个事务,并在结束时通过清除提交它(如果其他服务使用相同的EM并且需要避免脏读)
  • 我将重播前两个常见情况 - 批量处理一个并绕过所有可能的情况EM.因此在这种情况下,查询将被强制从DB查询,而不是从缓存中查询.
  • 您应该知道使用L1和L2缓存,L1是由EM清除的缓存.当您读取大量数据时(应该不是这种情况)(然后在一段时间内也需要清除).

如您所见,取决于您的平台的案例,架构和风格.直接用于你的方法 - 每个方法刷新和清除缓存不是一个好习惯,它是一种反模式方法.