Краткая версия: Как исправить объект JSON, содержащийся в поле Postgres jsonb
, используя метод PATCH Spring Data Rest PATCH?Spring Data Rest - PATCH Postgres jsonb field
Здесь идет длинная версия, пожалуйста, рассмотрим следующий объект:
@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
. Эти геттер/сеттер - это способ сериализации/десериализации его для Spring Data Rest, упомянутого here. Мы также попытались дать поле своему собственному типу, как указано в these answers.
Наша цель - исправить объект JSON, который содержит это поле, используя Spring Data Rest.
Например:
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"}
}
}
Спринг данных Остальные патчи Пример ресурс и переопределяет значение для каждого запрашиваемого атрибута, вместо того, чтобы пытаться вникнуть в свойства объекта JSON только для исправления запрошенных вложенных свойства.
Именно тогда, когда мы подумали, что поддержка весенних данных для поддержки 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, а не только ищет атрибуты сущности?
Nb: @Embeddable/@Embedded
Аннотации, скорее всего, следует избегать, поскольку они подразумевают знание вложенных имен свойств, что снизит процент для поля jsonb
.
Благодарим вас за чтение.
Да, мы идем по аналогичному решению. Единственная проблема, которая PostgreSQL, даже в 9.6, на самом деле не получает RFC слияния JSON. 'jsonb_set' отвечает на проблему, но ее нужно выполнить для каждого вложенного свойства. Мы желаем, чтобы оператор concactenate '' 'не слепо перезаписывал отсутствующие свойства, что было бы более полезным. Мы примем ваш ответ после ответа Дэвида Сиро. –
Думаю, в этом случае вы можете пойти с PL/v8 и создать пользовательскую функцию для выполнения таких исправлений. используя уже установленные решения (например, https://github.com/Starcounter-Jack/JSON-Patch) –