10

在工作中,我们正在开发一个 RESTful 应用程序,其中数据层将由 Hibernate 处理。但我们不确定如何处理实体更新。

我们计划做以下事情:

(
_
_带有版本号)返回服务器。
4) 服务器接收转换为 DTO 的 JSON。
5) 从 Hibernate 加载相应的实体,并将 DTO 的 props 复制到实体中。

=> 即使设置了客户端的版本号,实体也总是被覆盖。这是否意味着我们总是必须自己检查客户端的版本号和加载的实例的版本号,而不是 Hibernate 这样做?

在具有会话的常规应用程序中,分离的实例保存在 HttpSession 中。每当客户端更新实体时,都会从 HttpSession 检索实例并更新一些属性。每当 Hibernate 提交更新时,如果版本号 < 当前版本号,将抛出 ObjectStaleException。

这里的问题是我们没有任何 Http 会话,因为我们试图成为 RESTful。

是否有一个通用的解决方案来处理 RESTful 应用程序中的乐观锁定,而不是自己检查版本号?

4

3 回答 3

5

你的策略很好。只需将来自客户端的版本号复制到加载的实体中(或使用merge(),这将执行相同操作),当 Hibernate 刷新实体时,如果版本号已增加,您将遇到乐观锁异常。

你不需要自己检查任何东西。Hibernate 会为您进行检查。

于 2013-08-11T11:30:37.807 回答
1

自己检查版本的替代方法是构建实体对象并调用entityManager.merge,如果版本同时更改,它也应该触发乐观锁异常,但如果同时删除对象,它不会抛出。要正确处理,您必须自己检查。

您可以使用Blaze-Persistence 可更新实体视图而不是通过单独加载实体状态来实现这一点, 它是一个用于在 JPA 之上开发 DTO 的库,它还实现了对乐观锁定的支持。你的用例应该已经得到支持,虽然我还没有很好的 Spring WebMvc 集成,所以你现在必须自己做一些管道。不过,我对此有一些想法,这只是时间和相关方的问题,直到整合更加顺利。

可更新的实体视图允许映射实体的子集,并且只刷新该子集。由于使用了脏跟踪,它可以准确地知道发生了什么变化,从而可以进行细粒度的刷新。

所以PATCH support的想法,这似乎是你想要的,只是通过 id 获得一个对象的空引用。为空意味着它没有数据,即所有空值。脏跟踪假设初始状态全部为空。您可以简单地将请求有效负载映射到该对象上,如果值为 null,它不会将其识别为已更改,因此忽略它。如果设置了任何非空值,则它确定这样的字段是脏的,并且在刷新时,只刷新脏值。

我自己还没有尝试过,但你可以做这样的事情

// Create reference for the id, the object is empty i.e. all null except for the id
CustomerDTO dto = entityViewManager.getReference(CustomerDTO.class, someId);
// Map the payload on the DTO which will call setFoo(null) but that's ok, because that isn't considered being dirty
jsonMapper.map(requestPayload, dto);
// Flush dirty changes i.e. non-null values
entityViewManager.update(entityManager, dto);

使用PARTIAL刷新模式时执行的更新查询将仅包含具有非空值的属性的 set 子句。DTO 看起来像这样

@EntityView(Customer.class)
@UpdatableEntityView(mode = FlushMode.PARTIAL)
public interface CustomerDTO {
  @IdMapping Integer getId();
  String getName();
  void setName(String name);
  String getDesc();
  void setDesc(String desc);
}

如果没有脏东西,它甚至不会执行查询。

于 2018-07-19T18:21:11.587 回答
0

从服务器应用程序的数据库层来看,用户在大型机绿屏、HTML 表单或 REST 客户端中编辑数据没有区别。

数据从数据库中读取,呈现给用户(编辑时可能会去吃午饭或假期),然后写回数据库。

在 REST 应用程序的上下文中,乐观锁定没有什么特别之处。对 3270 或 HTML 屏幕有效的乐观锁定模式对基于 REST 的 Angular 应用程序仍然有效。

于 2021-10-21T20:21:53.227 回答