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's first name") // private String firstName; @Description("A person's last name") // private String lastName; @Description("A person's siblings") // @ManyToMany // private List siblings = new ArrayList(); @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
字段。 添加此项,添加注释,添加用于向人员添加订单的方法,然后在发送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 }
Order
和Person
类都应该实现Serializable
以便将它们正确分解并从JSON
重建它们。
有一些方法可以解决你的问题,但我想给你一个提示。 您只需要保存您个人的"id"
,并在需要时从数据库中获取"id"
。
它解决了您的问题,也节省了内存。
我相信你需要做两件事来完成这项工作。
- 正确处理反序列化。 正如您所期望Jackson通过构造函数填充嵌套的Person对象,您需要使用
@JsonCreator
对其进行注释。 看这里:
http://www.cowtowncoder.com/blog/archives/2011/07/entry_457.html
Jackson的一个更强大的function是它能够使用任意>构造函数来创建POJO实例,通过指示与
@JsonCreator
注释一起使用的构造函数………………… ………………….基于属性的创建者通常用于将一个或多个强制性参数传递给构造函数(直接或通过工厂方法)。 如果未从JSON中找到属性,则传递null (或者,如果是基元,则为所谓的默认值; 0表示整数,依此类推)。
另请参见此处为何jackson可能无法自动解决此问题。
https://stackoverflow.com/a/22013603/1356423
- 更新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; } }