Spring -data-rest интеграционный тест с ошибкой с простым запросом json
Мой тест интеграции 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 first name") //
private String firstName;
@Description("A person last name") //
private String lastName;
@Description("A person 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 order, передавая человеку
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. После этого весь мой клиентский код не работает.
Как это решить?
Ответы
Ответ 1
Вы правильно связываете порядок с создателем, однако Лицо не связано с заказами. Вам не хватает поля List<Order> orders
в классе Person. Добавьте это, добавьте аннотации, добавьте методы для добавления заказа для человека, а затем перед отправкой JSON вы должны вызвать что-то вроде этого:
creator.addOrder(order);
order.setCreator(cretr);
Ответ 2
Вы пытались использовать 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
}
Ответ 3
Оба класса Order
и Person
должны реализовать Serializable
, чтобы правильно их разбить и перестроить из JSON
.
Ответ 4
Есть несколько способов решить вашу проблему, но я хочу дать вам подсказку. Вы можете сохранить только "id"
своего лица и получить человека "id"
из своей базы данных, когда вам это нужно.
Он решает вашу проблему, а также сохраняет память.
Ответ 5
Я считаю, что вам нужно сделать две вещи, чтобы получить эту работу.
- Правильно выполните десериализацию. Поскольку вы ожидаете, что Джексон будет заполнять вложенный объект Person через конструктор, вам нужно аннотировать его с помощью
@JsonCreator
. См. Здесь:
http://www.cowtowncoder.com/blog/archives/2011/07/entry_457.html
Одной из более мощных функций Jackson является его способность использовать произвольные конструкторы для создания экземпляров POJO, указав конструктор для использования с @JsonCreator
аннотация........................................... Создатели, основанные на свойствах, обычно используются для передачи одного или нескольких обязательные параметры в конструкторе (прямо или через factoryметод). Если свойство не найдено из JSON, вместо него передается значение(или, в случае примитивов, так называемое значение по умолчанию; 0 для ints и так далее).
См. также здесь, почему Джексон, возможно, не сможет автоматически выполнить это.
fooobar.com/info/97757/...
- Обновите сопоставления JPA. Если связанное лицо теперь правильно заполнено десериализатором Джексона, то, добавив необходимые параметры каскада 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;
}
}