Spring数据-“手动"后刷新实体后端查询更新 [英] Spring data - Refresh entity after "manual" backend query update

查看:15
本文介绍了Spring数据-“手动"后刷新实体后端查询更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有这种情况:

我们以标准方式配置了 spring 数据,有一个 Respository 对象,一个 Entity 对象,一切正常.

We have spring data configured in the standard way, there is a Respository object, an Entity object and all works well.

现在对于一些复杂的动机,我必须直接使用 EntityManager(或 JdbcTemplate,任何低于 spring 数据的级别)来更新与我的 EntityManager 关联的表代码>实体,带有原生sql查询.所以我没有使用 Entity 对象,而只是在我用作实体的表上手动执行数据库更新(更正确地说是我从中获取值的表,请参阅下一行).原因是我必须将我的 spring-data Entity 绑定到一个 mysql 视图,该视图使多个表成为 UNION,而不是直接绑定到我需要更新的表.

Now for some complex motivations I have to use directly EntityManager (or JdbcTemplate, whatever is at a lower level than spring data) to update the table associated to my Entity, with a native sql query. So I'm not using Entity object, but simply doing a db update manually on the table I use as entity (is more correct to say the table from which I get values, see next rows). The reason is that I had to bind my spring-data Entity to a mysql view that makes UNION of multiple tables, not directly to table I need to update.

会发生什么:

在功能测试中,我调用先前描述的手动"更新方法(在创建 mysql 视图的表上)(通过实体管理器)和如果我制作一个简单的 Respository.findOne(objectId) 我得到旧对象(未更新).我必须调用 Entitymanager.refresh(object) 来获取更新的对象.

In a functional test I call "manual" update method (on table from which the mysql view is created) previously described (through entity-manager) AND 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.

为什么?

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

Is there a way to "synchronize" (out of the box) objects (or force some refresh) in spring-data? Or am I asking for a miracle? I'm not ironical, but maybe I'm not so expert, maybe (or probably) is my ignorance. If so please explain me why and (if you want) share some advanced knowledge about this amazing framework.

推荐答案

如果我做一个简单的 Respository.findOne(objectId) 我得到旧对象(不是更新了一个).我必须调用 Entitymanager.refresh(object) 来获取更新的对象.

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.

为什么?

一级缓存在会话期间处于活动状态.除非有理由返回数据库,否则之前在会话上下文中检索到的任何对象实体都将从一级缓存中检索.

The first-level cache is active for the duration of a session. Any object entity previously retrieved in the context of a session will be retrieved from the first-level cache unless there is reason to go back to the database.

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

Is there a reason to go back to the database after your SQL update? Well, as the book Pro JPA 2 notes (p199) regarding bulk update statements (either via JPQL or SQL):

开发者在使用这些[批量更新]语句时首先要考虑的问题是持久化上下文没有更新以反映结果的操作.批量操作作为 SQL 发出数据库,绕过持久化的内存结构上下文.

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.

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

which is what you are seeing. That is why you need to call refresh to force the entity to be reloaded from the database as the persistence context is not aware of any potential modifications.

本书还注意到以下有关使用 Native SQL 语句(而不是 JPQL 批量更新)的说明:

The book also notes the following about using Native SQL statements (rather than JPQL bulk update):

■ 注意本机 SQL 更新和删除操作不应在实体映射的表上执行.JP QL 操作告诉提供者必须使缓存的实体状态无效才能与数据库保持一致.本机 SQL 操作绕过这样的检查并可能迅速导致内存缓存不可用的情况与数据库有关.

■ 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.

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

Essentially then, should you have a 2nd level cache configured then updating any entity currently in the cache via a native SQL statement is likely to result in stale data in the cache.

这篇关于Spring数据-“手动"后刷新实体后端查询更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆