JAX-RS + JPA,如何 update/merge 仅显示实体字段的子集?
JAX-RS + JPA, how to update/merge only a subset of an Entity's fields?
假设我有以下实体:
@Entity
@XmlRootElement
@XmlAccessorType( XmlAccessType.FIELD)
public class MyEntity {
@Id
@GeneratedValue
private long id;
private boolean field1;
private boolean field2;
private boolean field3;
}
假设我有一个 REST Web 服务,允许客户端 POST 部分或完全更新 MyEntity 资源。也许方法签名看起来像这样:
@POST
@Path("{id}")
public Response postMyEntity(@PathParam("id") long id, MyEntity myEntity)
下面是 JSON,客户端可能会使用它来仅更新 ID 为 101 的 MyEntity 的 "field2":
{
"id": 101
"field2": true
}
如果 JPA 知道在反序列化过程中只设置了 field2,那么我很乐意使用如下简单的代码来保持此更改:
entityManager.merge(myEntity);
但是,此操作会更新 field1、field2 和 field3。
人们通常如何确保在数据库中仅更新 REST 请求的 JSON/XML 中明确指定的字段?我读过有人在他们的网络服务中使用 DTO(而不是实体本身)并手动找出需要在相应实体上设置哪些字段......但是,这个用例似乎很常见,我很惊讶这需要 DIY 方法。
也许有更好的解决方案,但我决定强制我的 REST 服务生成和使用 DTO 而不是实体。我的 DTO 类 从不使用基元(整数而不是 int),这确保如果客户端省略 JSON/XML 属性,则相应的 DTO 字段将为空。
当我收到 POST 更新资源时,我:
- 从数据库中获取对应的Entity。
- 将所有非空字段从 DTO 复制到实体。
- 使用 JPA 的合并功能更新数据库。
当我收到资源的 GET 时,我:
- 从数据库中获取实体。
- 将实体中的所有字段复制到新的 DTO。
- Return 客户端的 DTO。
设置这个很乏味,因为它需要我:
- 创建一堆 DTO 类 与相应的实体 类.
几乎相同
- 编写逻辑以在 DTO 和实体之间进行转换。
- 继续保持这种混乱状态。
我想我可以从我的实体 类 中删除基元,而不是使用 DTO,并向这些字段添加非空约束。但是,我在几个地方读到 "bad idea" 将您的实体 类 直接暴露给 REST 客户端。所以我继续使用 DTO 解决方案,尽管我不是它的最大粉丝。
假设我有以下实体:
@Entity
@XmlRootElement
@XmlAccessorType( XmlAccessType.FIELD)
public class MyEntity {
@Id
@GeneratedValue
private long id;
private boolean field1;
private boolean field2;
private boolean field3;
}
假设我有一个 REST Web 服务,允许客户端 POST 部分或完全更新 MyEntity 资源。也许方法签名看起来像这样:
@POST
@Path("{id}")
public Response postMyEntity(@PathParam("id") long id, MyEntity myEntity)
下面是 JSON,客户端可能会使用它来仅更新 ID 为 101 的 MyEntity 的 "field2":
{
"id": 101
"field2": true
}
如果 JPA 知道在反序列化过程中只设置了 field2,那么我很乐意使用如下简单的代码来保持此更改:
entityManager.merge(myEntity);
但是,此操作会更新 field1、field2 和 field3。
人们通常如何确保在数据库中仅更新 REST 请求的 JSON/XML 中明确指定的字段?我读过有人在他们的网络服务中使用 DTO(而不是实体本身)并手动找出需要在相应实体上设置哪些字段......但是,这个用例似乎很常见,我很惊讶这需要 DIY 方法。
也许有更好的解决方案,但我决定强制我的 REST 服务生成和使用 DTO 而不是实体。我的 DTO 类 从不使用基元(整数而不是 int),这确保如果客户端省略 JSON/XML 属性,则相应的 DTO 字段将为空。
当我收到 POST 更新资源时,我:
- 从数据库中获取对应的Entity。
- 将所有非空字段从 DTO 复制到实体。
- 使用 JPA 的合并功能更新数据库。
当我收到资源的 GET 时,我:
- 从数据库中获取实体。
- 将实体中的所有字段复制到新的 DTO。
- Return 客户端的 DTO。
设置这个很乏味,因为它需要我:
- 创建一堆 DTO 类 与相应的实体 类. 几乎相同
- 编写逻辑以在 DTO 和实体之间进行转换。
- 继续保持这种混乱状态。
我想我可以从我的实体 类 中删除基元,而不是使用 DTO,并向这些字段添加非空约束。但是,我在几个地方读到 "bad idea" 将您的实体 类 直接暴露给 REST 客户端。所以我继续使用 DTO 解决方案,尽管我不是它的最大粉丝。