java - 如何在 "manual"后端查询更新后刷新实体

标签 java persistence spring-data spring-data-jpa

<分区>

假设有这种情况:

我们以标准方式配置了 Spring Data,有一个 Respository 对象,一个 Entity 对象,一切正常。

现在出于一些复杂的动机,我必须直接使用 EntityManager(或 JdbcTemplate,无论级别低于 Spring Data)来更新关联到我的表 Entity,带有原生 SQL 查询。因此,我没有使用 Entity 对象,而只是在我用作实体的表上手动执行数据库更新(更正确的说法是我从中获取值的表,请参阅下一行)。

原因是我必须将我的 spring-data Entity 绑定(bind)到一个 MySQL View ,它使多个表成为 UNION,而不是直接绑定(bind)到我需要更新的表。

发生的事情是:

在功能测试中,我调用“手动”更新方法(在创建 MySQL View 的表上),如前所述(通过实体管理器),如果我做一个简单的 Respository.findOne(objectId ),我得到了旧对象(未更新的对象)。我必须调用 Entitymanager.refresh(object) 来获取更新后的对象。

为什么?

有没有办法在 spring-data 中“同步”(开箱即用)对象(或强制刷新)?还是我在祈求奇迹? 我不是讽刺,但也许我不是那么专家,也许(或可能)是我的无知。如果是,请向我解释原因并(如果你愿意)分享一些关于这个惊人框架的高级知识。

最佳答案

If I make a simple Respository.findOne(objectId) I get old object (not updated one). I've to call Entitymanager.refresh(object) to get updated object.

Why?

一级缓存在 session 期间处于 Activity 状态。除非有理由返回数据库,否则将从一级缓存中检索先前在 session 上下文中检索到的任何对象实体。

在 SQL 更新后是否有返回数据库的原因?好吧,正如 Pro JPA 2 书中关于批量更新语句(通过 JPQL 或 SQL)的注释 (p199):

The first issue for developers to consider when using these [bulk update] statements is that the persistence context is not updated to reflect the results of the operation. Bulk operations are issued as SQL against the database, bypassing the in-memory structures of the persistence context.

这就是你所看到的。这就是为什么您需要调用刷新以强制从数据库重新加载实体,因为持久性上下文不知道任何潜在的修改。

本书还对使用 Native SQL 语句(而不是 JPQL 批量更新)做了如下说明:

■ CAUTION Native SQL update and delete operations should not be executed on tables mapped by an entity. The JP QL operations tell the provider what cached entity state must be invalidated in order to remain consistent with the database. Native SQL operations bypass such checks and can quickly lead to situations where the inmemory cache is out of date with respect to the database.

从本质上讲,如果您配置了二级缓存,那么通过 native SQL 语句更新当前缓存中的任何实体可能会导致缓存中的数据过时。

关于java - 如何在 "manual"后端查询更新后刷新实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33825429/

相关文章:

java - 使用 Spring 数据创建 Cassandra 集群连接的最佳方法

java - 带默认值的 lombok 返回字段的 Spring Rest jackson

对于相同数量的键,Redis 超时消耗更多内存

java - 日期对象转换为 (mm/dd/yyyy) 中的日期对象

java - FXML TableView "Class fxmlPerson does not support property "bestellnr"

java - XML 保留前导空格,但不保留尾随空格

ios:关闭计算机时,带有 fmdb 的 Sqlite 插入不会保留在模拟器上

java - 当其子对象的状态更改时,父对象的版本不会更改

persistence - 在 Spring Statemachine 中持久化和恢复当前状态

java - Java 的 java.lang.Runtime.exec() 和 PHP 的 exec() 有什么区别?