0

当我使用 json-patch 时,我收到“无法从类型 [java.lang.String] 转换为类型 [@javax.persistence.Column java.util.Date] for value '1999-12-20' ”,但是使用 json-merge-patch 进行 PUT、POST 或事件 PATCH 请求时,我没有收到此错误;

我正在使用带有 Spring Data Rest 的 Spring Boot 版本 2.1.8。

我有一个实体,其字段类似于以下(只有变量和列的名称不同):

@Column(name = "mydate")
private Date mydate;

当我向正文发出 JSON 合并补丁请求时,该字段按预期更新:

{"mydate": "1999-12-20"}

它还使用 POST 和 PUT 请求正确更新。

但是,如果我使用以下命令(和 Content-Type application/json-patch+json)发出 json-patch:

[{"op":"replace","path":"mydate","value":"2018-08-09"}]

我收到上面提到的错误。

我实际上不需要解决方法,因为我为此使用了 JSON Merge Patch。

我想了解如何使适用于其他请求的转换也适用于 json-patch。

4

2 回答 2

1

这里有一个建议:由于 Java 8 类Date不应该被使用,它应该被替换为一些Temporal接口的实现。例如,在您的情况下LocalDate。至于此类属性的注释,您需要对其进行如下注释:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
public LocalDate myDate;

详情参考这个问题的答案:Spring Data JPA - ZonedDateTime format for json serialization

于 2020-01-14T14:34:15.047 回答
1

这是一种解决方法,而不是正确的解决方案。

我仍然不明白为什么会发生这种情况,但这里有两个解决方法可以帮助下一个在这个问题上绊倒的可怜人:

使用 JSON 合并补丁

带有 JSON Merge Patch 的补丁请求的日期字段由 SDR 正确解释。如果可能,只需从使用 JSON Patch 切换到 JSON Merge Patch 即可解决问题。

使用虚拟字段

我找不到一种方法来帮助 Spring Data Rest 在收到 JSON Patch 请求时使用转换器,因此在您的 DTO(或者最糟糕的 - 在您的实体中)创建一个虚拟字符串字段将解决该问题。

如果您不能或不想避免使用json-patch,这可能会有所帮助。

这不是一个漂亮的解决方案,看到它可能会叫你名字,但它会起作用。

考虑以下 - 最坏情况 - 代码:

@Entity
public class MyRenderVouz {
    ...
    @Column(name="important_date")
    private LocalDate importantDate;
    
    @Transient
    private String strChangeImportantDate;
    public void setStrChangeImportantDate(String newDate) {
        setImportantDate(LocaleDate.parse(newDate);
    }
    public String getStrChangeImportantDate() {
        return this.importantDate;
    }
    ...
}

在您的 JSON-PATCH 中,简单地使用 strChangeImportantDate 而不是 importantDate,例如,考虑您要更新属于日历的 MyRendezVouz 的第二个实例的 importantDate:

Calendar
 L importantRenderVouz  []
    L myRenderVouz
    L myRenderVouz
        L importantDate // target date
    L myRenderVouz

然后你可以使用:

[
    {"op":"replace","path":"importantRenderVouz/1/strImportantDate","value":"2020-01-01"},  
]
于 2020-01-23T17:19:33.690 回答