My spring-data-rest integration test fails for a simple json request. Consider the below jpa models
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
}
In my test I created a person by using personRepository and inited order by passing person
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());
Order is created but creator is not associated with the order. Also I want to pass request body as a json object. In this my json object should contain creator as follows
{
"type": "1",
"creator": {
"id": 1,
"firstName": "Joe",
"lastName": "Keith",
"age": 30
}
}
If I send request body with the following json, the call works fine
{
"type": "1",
"creator": "http://localhost/people/1"
}
But I don't want to send the second json. Any idea how to solve the issue. Because already my client is consuming the server response by sending first json. Now I migrated my server to use spring-data-rest. After that all my client code is not working.
How to solve this?
You are correctly associating order with the creator, however the Person is not associated with the orders. You are missing the List<Order> orders
field in Person class. Add this, add annotations, add methods for adding order to person and then before sending JSON you should call something like this:
creator.addOrder(order);
order.setCreator(cretr);
Did you try using cascade = CascadeType.ALL
in @ManyToOne annotation
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
重建它们。
There are some ways to solve your problem, but I want give you a hint. You just can save only "id"
of your person and get the person by "id"
from your database, when you need this.
It solves your problem and it also saves the memory.
I believe you need to do two things to get this work.
@JsonCreator
. See here: http://www.cowtowncoder.com/blog/archives/2011/07/entry_457.html
One of more powerful features of Jackson is its ability to use arbitrary >constructors for creating POJO instances, by indicating constructor to use with
@JsonCreator
annotation ........................................... Property-based creators are typically used to pass one or more obligatory parameters into constructor (either directly or via factory method). If a property is not found from JSON, null is passed instead (or, in case of primitives, so-called default value; 0 for ints and so on).
See also here on why Jackson may not be able to automatically work this out.
https://stackoverflow.com/a/22013603/1356423
I think then the following should work as expected:
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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.