prosource

spring-data-rest 통합 테스트가 simple json 요청으로 실패함

probook 2023. 2. 27. 22:27
반응형

spring-data-rest 통합 테스트가 simple json 요청으로 실패함

단순한 json 요청에 대한 스프링 데이터-레스트 통합 테스트에 실패했습니다.다음 jpa 모델을 고려하십시오.

Order.java

public class Order {

    @Id @GeneratedValue//
    private Long id;
    @ManyToOne(fetch = FetchType.LAZY)//
    private Person creator;
    private String type;

    public Order(Person creator) {
        this.creator = creator;
    }

    // getters and setters
}

Person.java

ic class Person {

    @Id @GeneratedValue private Long id;

    @Description("A person's first name") //
    private String firstName;

    @Description("A person's last name") //
    private String lastName;

    @Description("A person's siblings") //
    @ManyToMany //
    private List<Person> siblings = new ArrayList<Person>();

    @ManyToOne //
    private Person father;

    @Description("Timestamp this person object was created") //
    private Date created;

    @JsonIgnore //
    private int age;

    private int height, weight;
    private Gender gender;

    // ... getters and setters
}

테스트에서 personRepository를 사용하여 사람을 만들고 합격자별로 순서를 입력했습니다.

Person creator = new Person();
creator.setFirstName("Joe");
creator.setLastName("Keith");
created.setCreated(new Date());
created.setAge("30");
creator = personRepository.save(creator);

Order order = new Order(creator);
String orderJson = new ObjectMapper().writeValueAsString(order);

mockMvc.perform(post("/orders").content(orderJson).andDoPrint());

주문이 생성되었지만 작성자가 주문과 연결되어 있지 않습니다.또한 요청 본문을 json 오브젝트로 전달하고 싶습니다.이 경우 내 json 개체는 다음과 같은 생성자를 포함해야 합니다.

{
"type": "1",
"creator": {
    "id": 1,
    "firstName": "Joe",
    "lastName": "Keith",
    "age": 30
}
}

다음 json과 함께 요청 본문을 보내면 콜이 정상적으로 동작합니다.

{
"type": "1",
"creator": "http://localhost/people/1"
}

하지만 나는 두번째 json을 보내고 싶지 않다.이 문제를 어떻게 해결할지 생각나는 거 없어?클라이언트가 이미 first json을 전송하여 서버 응답을 소비하고 있기 때문입니다.이제 spring-data-rest를 사용하기 위해 서버를 마이그레이션했습니다.그 후 모든 클라이언트 코드가 작동하지 않습니다.

어떻게 해결할까요?

주문을 작성자와 올바르게 연결했지만, 사용자가 주문과 연결되지 않았습니다.놓치고 있습니다.List<Order> orders사용자 클래스의 필드.이것을 추가하고, 주석을 추가하고, 순서를 추가하는 방법을 사용자에게 추가한 후 JSON을 전송하기 전에 다음과 같이 호출해야 합니다.

creator.addOrder(order);
order.setCreator(cretr);

사용해보셨나요?cascade = CascadeType.ALL@ManyToOne 주석에서

public class Order {
    @Id @GeneratedValue//
    private Long id;
    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)//
    private Person creator;
    private String type;

    public Order(Person creator) {
        this.creator = creator;
    }

    // getters and setters
}

둘 다Order그리고.Person클래스는 실장해야 합니다.Serializable적절히 분해하여 재건하다JSON.

당신의 문제를 해결할 몇 가지 방법이 있지만, 힌트를 주고 싶어요.저장만 가능합니다."id"상대방을 설득하다"id"필요한 경우 데이터베이스에서 확인할 수 있습니다.

문제가 해결되고 메모리도 절약됩니다.

이 일을 하려면 두 가지 일을 해야 한다고 생각해요.

  1. 역직렬화를 적절히 처리한다.Jackson이 컨스트럭터를 통해 중첩된 Person 객체를 채울 것으로 예상되므로 주석을 달아야 합니다.@JsonCreator를 참조해 주세요.

http://www.cowtowncoder.com/blog/archives/2011/07/entry_457.html

잭슨의 가장 강력한 기능 중 하나는 POJO 인스턴스를 작성하기 위해 임의의 > 컨스트럭터를 사용할 수 있다는 것입니다.컨스트럭터를 사용할 수 있습니다.@JsonCreator주석 ............................................속성 기반 생성자는 일반적으로 하나 이상의 필수 매개 변수를 생성자에게 직접 전달하거나 공장 방법을 통해 전달하기 위해 사용됩니다.JSON에서 속성을 찾을없는 경우 대신 null이 전달됩니다(원본의 경우 기본값, ints의 경우 0 등).

잭슨이 이 문제를 자동으로 해결할 수 없는 이유에 대해서도 여기를 참조하십시오.

https://stackoverflow.com/a/22013603/1356423

  1. JPA 매핑을 업데이트합니다.연관된 사용자가 Jackson deserializer에 의해 올바르게 입력된 경우 필요한 JPA 캐스케이드옵션을 관계에 추가하여 두 인스턴스를 모두 유지해야 합니다.

그러면 다음 사항이 예상대로 작동해야 한다고 생각합니다.

public class Order {

    @Id 
    @GeneratedValue(...)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY, cascade = cascadeType.ALL)
    private Person creator;

    private String type;

    @JsonCreator
    public Order(@JsonProperty("creator") Person creator) {
        this.creator = creator;
    }
}

언급URL : https://stackoverflow.com/questions/40990415/spring-data-rest-integration-test-fails-with-simple-json-request

반응형