从v.2.5.7开始,Spring Data REST-PUT请求无法正常工作 [英] Spring Data REST - PUT request does not work properly since v.2.5.7

查看:54
本文介绍了从v.2.5.7开始,Spring Data REST-PUT请求无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自版本 2.5.7 起,Spring Data REST无法正确执行 PUT 请求以更新具有关联资源的资源.不同于PATCH请求可以正常工作!

Since version 2.5.7 Spring Data REST does not properly perform a PUT request to update resource which has associated resources. Unlike PATCH request that works as expected!

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

For example, Person has a many-to-one association with Addres. If we perform a PUT request with SDR v.2.5.6 (Spring Boot v.1.4.3) then all works OK. But if we switch to version 2.5.7 (i.e. to Spring Boot v.1.4.4) then we get an error:

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

Can not construct instance of Address: no String-argument constructor/factory method to deserialize from String value

其他类型的关联也是如此,例如,一对多(单向和双向)关联-请参阅我的

The same happens with other types of associations, for example with one-to-many (uni- and bidirectional) - see my example application code and tests.

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

This problem is present in all versions of the Spring Boot since 1.4.4 including the latest stable 1.5.6 version, as well as the newest 2.0.0-SNAPSHOT version!

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

To work around this situation we can just switch to SDR v.2.5.6 (Spring Boot v.1.4.3).

我已准备好邮递员要求集,以帮助您解决该问题:

I've prepared a Postman collection of requests to help you play with the issue: SDR PUT Issue

更新2017-08-14

我找到了避免错误的方法.无法构造Address的实例:没有用于从字符串值反序列化的字符串参数构造函数/工厂方法.

I found how to avoid the error Can not construct instance of Address: no String-argument constructor/factory method to deserialize from String value.

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

Since I'm using Lombok in this project, it is necessary just to tell Lombok to suppress using the @ConstructorProperties annotation in generated constructors. So I set lombok.anyConstructor.suppressConstructorProperties=true in the 'lombok.config' file and the error was gone.

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

Unfortunately a new problem was found - PUT request does not update associated objects at all!

下面的示例演示了这一点.当我们尝试通过将Person的地址从 addresses/1 (初始值)更改为 addresses/2 来更新Person时,则它保持不变: addresses/1!与以前的问题一样,自1.4.4(SDR-v.2.5.7起)以来,所有版本的Spring Boot中都存在此问题.

The example below is demonstrating this. When we are trying to update Person by changing his Address from addresses/1 (initial value) to addresses/2 - then it remains the same: addresses/1! As well as the previous problem this one is present in all versions of the Spring Boot since 1.4.4 (SDR - from v.2.5.7).

我调试了项目,发现问题的原因隐藏在方法 DomainObjectReader#mergeForPut 中(请参见

I debugged my project and found out that the reason of the issue is hidden in the method DomainObjectReader#mergeForPut (see its source) - it never replaces associated resources with new ones.

在我将此问题发布到 Spring JIRA 之前,请在此处报告这个问题在您的项目中以及您对此有何看法.

Before I post this issue on Spring JIRA, please report here if you have this issue in your projects and what do you think about it.

您可以得到我的测试

You can get my test here and check it in your projects - the test is 'standalone' and doesn't depend from other classes/modules (exclude only H2, I hope).

@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"
        }
    }
}

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

Then checking for a 'new' Address of Person - address was not updated:

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. answer ,事实证明SDR有一个 bug ,即在两张票证中进行了描述: DATAREST-1001

Thanks to Scott C. answer, it turned out that SDR has a bug, which is described in two tickets: DATAREST-1001 and DATAREST-1012.

推荐答案

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

Looks like the issue has already been reported as a bug: - please verify. As best as I can tell, this is the issue you are reporting above.

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

Note, I am revising my previous answer to be this bug report.

这篇关于从v.2.5.7开始,Spring Data REST-PUT请求无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆