Mar*_*eim 6 rest jpa jax-rs forward-compatibility
我有一个概念性的问题,我希望有人可能有答案.
我有一个RESTful服务,它为单一类型的实体提供类似CRUD的操作.实体(让我们称之为命令)使用Jackson表示为JSON.Jackson注释直接附加到实体类,没有明确的数据传输层.实体类包含许多属性,一对一和一对多关系.
从技术上讲,它基于Wildfly 10,JAX-RS 2.0和JPA 2.1(使用Hibernate 5).
目前支持的操作是:
orders/123 读取实体EntityManager.findorders/123 创建或替换实体EntityManager.persistEntityManager.merge该实体的简化版本如下所示:
@Entity
@Table(name = "order")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_EMPTY)
public class Order {
@Id
@SequenceGenerator(name = "order_id", sequenceName = "order_id_seq", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="order_id")
@Column(name = "id")
private long id;
@Version
private long version;
@Column(name = "correlation_id", unique = true)
private long correlationId;
@OneToOne(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonManagedReference
private SubOrder subOrder;
}
@Entity
@Table(name = "suborder")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_EMPTY)
public class SubOrder {
@Id
@SequenceGenerator(name = "suborder_id", sequenceName = "suborder_id_seq", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="suborder_id")
@Column(name = "id")
private long id;
@Version
private long version;
@OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", foreignKey = @ForeignKey(name = "suborder_order_FK1"))
@JsonBackReference
private Order order;
@Column(name = "field1", length = CommonConstants.LENGTH_4, nullable = true)
private String field1;
}
Run Code Online (Sandbox Code Playgroud)
JSON表示形式如下所示:
{
"id": 6000000197444,
"version": 358,
"correlationId": 4711,
"suborder": {
"id": 1000000005025,
"version": 40,
"field1": "value"
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想向实体添加字段field2Order.该服务有多个客户端 - Client1和Client2.
Client1执行实体的更新,并为新字段赋值newValue:
{
"id": 6000000197444,
"version": 358,
"correlationId": 4711,
"field2": "newValue",
"suborder": {
"id": 1000000005025,
"version": 40,
"field1": "value"
}
}
Run Code Online (Sandbox Code Playgroud)
Client2对新字段不感兴趣.因此,没有开发新版本的Client2.现在,它想要将值更改field1为值AnotherNewValue.由于它不知道新字段field2,它将以下JSON提供给服务:
{
"id": 6000000197444,
"version": 358,
"correlationId": 4711,
"suborder": {
"id": 1000000005025,
"version": 40,
"field1": "newValue"
}
}
Run Code Online (Sandbox Code Playgroud)
或者,Client1决定再次删除该值field2.因为该值现在为空,并且根据Jackson注释,不包括空值,以下JSON正在被PUT:
{
"id": 6000000197444,
"version": 358,
"correlationId": 4711,
"suborder": {
"id": 1000000005025,
"version": 40,
"field1": "newValue"
}
}
Run Code Online (Sandbox Code Playgroud)
此解决方案提供了一个严重的问题: 使用较旧的实体表示的客户端将意外删除其未知的字段.
所以基本上它会突破兼容性,这对我来说是个大问题!
我有一些可能的解决方案,但每个都有严重的缺点:
我认为这是一个非常常见的问题所以我希望你们中的一些人已经做过类似的事情了.我有具体的问题:1.有没有人知道允许在arbirtary对象树上创建和应用补丁的Java库(如解决方案2和3中所要求的)?2.有没有人有更简单的解决方案?
很抱歉,文字变得太长了,但我想要包含所有相关细节.非常感谢您的宝贵时间!
| 归档时间: |
|
| 查看次数: |
201 次 |
| 最近记录: |