一尘不染

从v.2.5.7开始,Spring Data REST-PUT请求无法正常工作

spring-boot

从版本 2.5.7开始, Spring Data REST无法正确执行 PUT 请求以更新 具有关联资源的资源
。与PATCH请求不同,它可以按预期工作!

例如,与Person有多对一关联Addres。如果我们使用SDR v.2.5.6(Spring Boot
v.1.4.3)执行PUT请求,则一切正常。但是,如果我们切换到版本2.5.7(即Spring Boot v.1.4.4),则会收到错误消息:

无法构造Address的实例:没有要从String值反序列化的String-argument构造函数/工厂方法

其他类型的关联也会发生同样的情况,例如一对多(单向和双向)关联-请参阅我的 示例应用程序 代码和测试。

从1.4.4开始的 所有 版本的Spring Boot 中
存在此问题,包括最新的稳定的1.5.6版本以及最新的2.0.0-SNAPSHOT版本!

要解决这种情况,我们可以切换到SDR v.2.5.6(Spring Boot v.1.4.3)。

我已经准备好 邮递员要求的集合, 以帮助您解决此问题:SDR
PUT问题

更新2017-08-14

我找到了避免错误的方法Can not construct instance of Address: no String-argument constructor/factory method to deserialize from String value

由于我在该项目中使用Lombok,因此仅需告诉Lombok禁止@ConstructorProperties生成的构造函数中使用注释即可
。所以我lombok.anyConstructor.suppressConstructorProperties=true在“
lombok.config”文件中设置,错误消失了。

不幸的是,发现了一个 新问题 -PUT请求根本不更新关联的对象

下面的示例演示了这一点。当我们试图从改变自己的地址,更新的人addresses/1(初始值)addresses/2-那么它仍然是相同的:addresses/1!与以前的问题一样,自1.4.4(SDR-v.2.5.7起)以来,
所有 版本的Spring Boot 中 存在此问题。

我调试了项目,发现问题的原因隐藏在方法中DomainObjectReader#mergeForPut(请参见其源代码)-它
永远不会 用新资源替换关联的资源。

在此问题发布到Spring JIRA上之前,
如果您的项目中有此问题以及您对此有何看法 ,请 在此处报告

您可以在此处获得我的测试并在项目中进行检查-
测试是“独立的”,并且不依赖于其他类/模块(我希望仅排除H2)。

@Entity
public class Person {

    private String name;

    @ManyToOne
    private Address address;

    // other stuff
}

@Entity    
public class Address {

    private String street;

    // other stuff
}

尝试更新人:

PUT http://localhost:8080/api/persons/1



{
    "name": "person1u",
    "address": "http://localhost:8080/api/addresses/2"
}

得到正确的回应:

{
    "name": "person1u",
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/persons/1"
        },
        "person": {
            "href": "http://localhost:8080/api/persons/1"
        },
        "address": {
            "href": "http://localhost:8080/api/persons/1/address"
        }
    }
}

然后检查人员的“新”地址-地址未更新:

GET http://localhost:8080/api/persons/1/address



{
    "street": "address1",
    "_links": {
        "self": {
            "href": "http://localhost:8080/api/addresses/1"
        },
        "address": {
            "href": "http://localhost:8080/api/addresses/1"
        }
    }
}

更新2017-08-24

多亏了Scott C.的回答,事实证明SDR有一个 错误 ,该错误
在两张票中进行了描述:DATAREST-1001DATAREST-1012


阅读 311

收藏
2020-05-30

共1个答案

一尘不染

该问题似乎已被报告为错误:-请验证。据我所知,这就是您在上面报告的问题。

注意,我正在将以前的答案修改为此错误报告。

2020-05-30