【发布时间】:2017-03-14 23:43:11
【问题描述】:
简短的版本是:如何使用 Spring Data Rest PATCH 方法修补 Postgres jsonb 字段中包含的 JSON 对象?
长版来了,请考虑以下实体:
@Entity
@Table(name = "examples")
public class Example {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String jsonobject;
@JsonRawValue
public String getJsonobject() {
return jsonobject == null ? null : jsonobject;
}
public void setJsonobject(JsonNode jsonobject) {
this.jsonobject = jsonobject == null ? null : jsonobject.toString();
}
}
jsonobject 是 Postgres 类型 jsonb。这些 getter/setter 是为 here 提到的 Spring Data Rest 序列化/反序列化它的方法。如these answers 中所述,我们还尝试为该字段提供自己的类型。
我们的目标是使用 Spring Data Rest 修补此字段包含的 JSON 对象。
例如:
GET /examples/1
{
"id": 1,
"jsonobject": {
"foo": {"bar": "Hello"},
"baz": 2
}
}
PATCH /examples/1
{
"jsonobject": {
"foo": {"bar": "Welcome"}
}
}
预期输出:
GET /examples/1
{
"id": 1,
"jsonobject": {
"foo": {"bar": "Welcome"},
"baz": 2
}
}
当前输出:
GET /examples/1
{
"id": 1,
"jsonobject": {
"foo": {"bar": "Welcome"}
}
}
Spring Data Rest 修补 Example 资源并覆盖每个请求属性的值,而不是尝试挖掘 JSON 对象的属性以仅修补请求的嵌套属性。
这时我们认为 Spring Data Rest 对 application/merge-patch+json 和 application/json-patch+json 媒体类型的支持会派上用场。以下是每种媒体类型的输出:
application/merge-patch+json:
PATCH /examples/1
{
"jsonobject": {
"foo": {"bar": "Welcome"}
}
}
输出:
GET /examples/1
{
"id": 1,
"jsonobject": {
"foo": {"bar": "Welcome"}
}
}
application/json-patch+json:
PATCH /examples/1
[
{ "op": "replace", "path": "/jsonobject/foo/bar", "value": "Welcome" }
]
输出:
{
"cause": {
"cause": null,
"message": "EL1008E:(pos 8): Property or field 'foo' cannot be found on object of type 'java.lang.String' - maybe not public?"
},
"message": "Could not read an object of type class com.example.Example from the request!; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 8): Property or field 'foo' cannot be found on object of type 'java.lang.String' - maybe not public?"
}
这归结为相同的想法:只查找实体属性,并且要么完全覆盖,要么找不到。
问题如下:有没有办法让 Spring Data Rest 了解它正在处理 jsonb 字段,从而查找 JSON 嵌套属性,而不仅仅是查找实体属性?
注意:@Embeddable/@Embedded 注释最有可能被避免,因为它们意味着知道嵌套的属性名称,这会降低对 jsonb 字段的兴趣。
感谢您的阅读。
【问题讨论】:
标签: spring postgresql spring-data-rest jsonb json-patch