簡體   English   中英

spring-data-rest集成測試因簡單的json請求而失敗

[英]spring-data-rest integration test fails with simple json request

我的spring-data-rest集成測試因簡單的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和inited命令創建了一個人

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。 任何想法如何解決問題。 因為我的客戶端已經通過發送第一個json來消耗服務器響應。 現在我遷移了我的服務器以使用spring-data-rest。 之后我的所有客戶端代碼都無法運行。

怎么解決這個?

您正確地將訂單與創建者關聯,但是Person與訂單無關。 您缺少Person類中的List<Order> orders字段。 添加此項,添加注釋,添加向人員添加訂單的方法,然后在發送JSON之前,您應該調用以下內容:

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

您是否嘗試在@ManyToOne注釋中使用cascade = CascadeType.ALL

 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 } 

OrderPerson類都應該實現Serializable以便將它們正確分解並從JSON重建它們。

有一些方法可以解決你的問題,但我想給你一個提示。 你只可以只保存"id"的人,並得到由人"id"從你的數據庫,當你需要這個。

它解決了您的問題,也節省了內存。

我相信你需要做兩件事來完成這項工作。

  1. 正確處理反序列化。 正如您所期望Jackson通過構造函數填充嵌套的Person對象,您需要使用@JsonCreator注釋它。 看這里:

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

Jackson的一個更強大的功能是它能夠使用任意>構造函數來創建POJO實例,通過指示與@JsonCreator注釋一起使用的構造函數..................... ......................基於屬性的創建者通常用於將一個或多個必需參數傳遞給構造函數(直接或通過工廠方法)。 如果未從JSON中找到屬性,則傳遞null (或者,如果是基元,則為所謂的默認值; 0表示int,依此類推)。

另請參見此處為何傑克遜可能無法自動解決此問題。

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

  1. 更新JPA映射。 如果關聯的Person現在由Jackson反序列化器正確填充,那么通過向關系添加必要的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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM