OpenJPA 在使用 JPQL(select 查询)重新获取实体时不会刷新实体

OpenJPA does not refresh entity on re-fetching of entity using JPQL(select query)

该问题特定于持久性上下文 (L1) 中的缓存,而不是二级缓存。

我想知道为什么在使用 JPQL 的实体 selection/re-loading 上不刷新持久上下文缓存中的实体。

用例子解释问题:

  1. 事务 A 的开始
  2. 在事务 A 的持久上下文中加载实体 A。
  3. 事务A中的一些其他处理。但是没有修改加载的实体。同时,同一实体在另一个事务 B 中被修改和提交,即在另一个持久上下文中。
  4. 使用 JPQL(select 子句)在事务 1 中重新加载实体 A。实体 A 具有陈旧的属性。

我在日志中验证了查询已被触发。那为什么实体A没有刷新呢?

这是一级缓存的工作方式。当 OpenJPA 读取查询的结果集时,它会检查结果集行的 id 字段。如果具有该 id 的实体已经存在于持久性上下文中,则使用现有实体并忽略结果集行的其余部分,这意味着不会再次组装该实体。

如果你想强制重新加载一个实体实例,你可以:

  1. Refresh吧。
  2. Detach 这样当持久性提供程序在它执行的任何后续操作中查找它时,将从数据库加载一个新的托管。
  3. Clear 整个持久性上下文,以便持久性提供程序在同一事务的任何后续操作中再次重新加载它需要的所有内容。

根据用例,您可能希望 flush 在您打算 refresh/detach/clear 应用任何上述操作之前,您可能在实例中所做的任何更改,否则这些更改将不会与数据库同步。