programing

Spring Data REST - PUT 요청이 v.2.5.7 이후 제대로 작동하지 않음

sourcejob 2023. 8. 22. 22:06
반응형

Spring Data REST - PUT 요청이 v.2.5.7 이후 제대로 작동하지 않음

버전 2.5.7 Spring Data REST는 연결리소스가 있는 리소스를 업데이트하기 위해 PUT 요청을 제대로 수행하지 않습니다.예상대로 작동하는 PATCH 요청과 달리!

를 들면, 들면를예,Person는 와의다1 있습다니와 .AddresSDR v.2.5.6(Spring Boot v.1.4.3)에서 PUT 요청을 수행하면 모든 것이 정상적으로 작동합니다.그러나 버전 2.5.7(즉, Spring Boot v.1.4.4)로 전환하면 다음 오류가 발생합니다.

주소의 인스턴스를 구성할 수 없습니다. String 값에서 역직렬화할 String-argument 생성자/공장 메서드가 없습니다.

일대일(uni-to-many) 및 양방향(bidirectional)과 같은 다른 유형의 연결에서도 동일한 현상이 발생합니다. 응용 프로그램 코드 및 테스트 예제를 참조하십시오.

이 문제는 안정적인 최신 1.5.6 버전과 최신 2.0.0-SNAPHOT 버전을 포함하여 1.4.4 이후의 모든 버전의 Spring Boot에서 발생합니다!

이 문제를 해결하려면 SDR v.2.5.6(Spring Boot v.1.4.3)으로 전환하면 됩니다.

는 당신이 이 문제를 해결하는 데 도움이 될 수 있도록 포스트맨 요청 모음을 준비했습니다: SDR PUT Issue

업데이트 2017-08-14

를 피하는 .Can not construct instance of Address: no String-argument constructor/factory method to deserialize from String value.

이 프로젝트에서 롬복을 사용하고 있기 때문에 롬복에게 사용을 자제하라고 말하는 것이 필요합니다.@ConstructorProperties생성된 생성자의 주석입니다.그래서 설정했습니다.lombok.anyConstructor.suppressConstructorProperties=true하지 않았습니다filename에 저장되어 있습니다.

안타깝게도 새로운 문제가 발견되었습니다. PUT 요청이 관련 개체를 전혀 업데이트하지 않습니다!

아래의 예는 이를 보여줍니다.주소를 변경하여 사용자를 업데이트하려는 경우addresses/1 ~ (초기값) ~addresses/2됩니다: 그면그유지니됩다대로러다니▁then.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에 버그가 있는 것으로 밝혀졌는데, 이 버그는 DATREST-1001DATREST-1012 두 티켓에 설명되어 있습니다.

문제가 이미 버그로 보고된 것 같습니다. - 확인하십시오.제가 아는 한, 이것은 당신이 위에서 보고하고 있는 문제입니다.

참고, 이전 답변을 이 버그 보고서로 수정합니다.

이것이 Spring Data REST의 버그이며 보고되어야 한다는 당신의 의견에 동의합니다.

PATCH 요청을 통해 엔티티를 업데이트하는 것은 문제가 없지만 PUT 요청은 지정된 엔티티의 필드만 업데이트하고 관련 리소스는 업데이트하지 않습니다.

왜 제가 이것을 버그로 간주할까요?

  • 사람들이 올바르게 지적했듯이, PUT는 전체 리소스를 수정된 버전으로 교체하는 데 사용되어야 하며, POST 요청에서와 같이 리소스에 대한 모든 필드를 제공하는 경우 PUT가 작동해야 합니다.그러나 현재 Spring Data REST 버전에서는 엔티티의 단순 필드만 업데이트되고 관련 리소스는 그대로 유지되므로 PUT 요청이 "부분적으로만 작동"되며 이는 RFC를 충족하더라도 예상된 동작이 아닙니다.
  • 또한 Spring Data REST를 사용하면 PUT 작업을 통해 이름 필드만 업데이트하는 등 부분 PUT 요청도 수행할 수 있습니다.하지만 주소에 대해서는 작동하지 않습니다.
  • 즉, Spring Data REST는 RFC가 지정하는 방식으로 정확히 작동하지 않지만(다른 토론을 위한 일 수도 있음), 한 필드를 업데이트하면 오류의 징후가 없는 다른 필드를 업데이트하는 경우에도 일관된 사용법을 제공하지 않습니다.

참고로 Spring Data REST 2.6.3을 사용하고 있습니다.

언급URL : https://stackoverflow.com/questions/45620195/spring-data-rest-put-request-does-not-work-properly-since-v-2-5-7

반응형