Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json JAX-RS+;JPA,如何仅更新/合并实体的子集';s场?_Json_Jpa_Jax Rs - Fatal编程技术网

Json JAX-RS+;JPA,如何仅更新/合并实体的子集';s场?

Json JAX-RS+;JPA,如何仅更新/合并实体的子集';s场?,json,jpa,jax-rs,Json,Jpa,Jax Rs,假设我有以下实体: @Entity @XmlRootElement @XmlAccessorType( XmlAccessType.FIELD) public class MyEntity { @Id @GeneratedValue private long id; private boolean field1; private boolean field2; private boolean field3; } 假设我有一个RESTWeb

假设我有以下实体:

@Entity
@XmlRootElement
@XmlAccessorType( XmlAccessType.FIELD)
public class MyEntity {

    @Id
    @GeneratedValue
    private long id;

    private boolean field1;

    private boolean field2;

    private boolean field3;
}
假设我有一个RESTWeb服务,它允许客户端向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);
但是,此操作会更新字段1、字段2和字段3


人们通常如何确保数据库中只更新REST请求中JSON/XML中显式指定的字段?我读过一些关于人们在web服务中使用DTO(而不是实体本身)并手动确定需要在相应实体上设置哪些字段的文章……但是,这个用例看起来如此普遍,以至于我很惊讶它需要DIY方法。

也许有更好的解决方案,但我决定强制我的REST服务生成和使用DTO,而不是实体。我的DTO类从不使用原语(Integer而不是int),这确保了如果客户机省略了JSON/XML属性,那么相应的DTO字段将为null

当我收到更新资源的帖子时,我:

  • 从数据库中获取相应的实体
  • 将所有非空字段从DTO复制到实体
  • 使用JPA的合并功能来更新数据库
  • 当我收到资源的GET时,我:

  • 从数据库中获取实体
  • 将实体中的所有字段复制到新DTO
  • 将DTO返回到客户端
  • 设置此设置非常繁琐,因为它需要我:

  • 创建一组与相应实体类几乎相同的DTO类
  • 写入逻辑以在DTO和实体之间转换
  • 继续保持这种混乱
  • 我想我可以从实体类中删除原语,并向这些字段添加NOTNULL约束,而不是使用DTO。然而,我在一些地方读到,直接向REST客户机公开实体类是一个“坏主意”。所以我继续使用DTO解决方案,尽管我不是它的最大粉丝