Подтвердить что ты не робот

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. После этого весь мой клиентский код не работает.

Как это решить?

4b9b3361

Ответ 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/...

  1. Обновите сопоставления 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;
    }
}