我正在写一个简单的订单付款一对一关联:
订购类相关代码:
@Entity
public class Order implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
(...)
@OneToOne(cascade=CascadeType.ALL, mappedBy="order")
private Payment payment;
付款类相关代码:
@Entity
public class Payment implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne
@MapsId
private Order order;
然后,我想实现一种基本方法来使用弹簧数据JPA存储库来播种我的测试数据库,但是如果我尝试以下代码,我会得到一个PersistentObjectException
说detached entity passed to persist
:
Order o1 = new Order(null, Instant.parse("2019-06-20T19:53:07Z"));
orderRepository.save(o1);
Payment p1 = new Payment(null, Instant.parse("2019-06-23T13:02:55Z"), o1);
paymentRepository.save(p1);
如果我这样尝试的话,也会发生同样的问题:
Order o1 = new Order(null, Instant.parse("2019-06-20T19:53:07Z"));
Payment p1 = new Payment(null, Instant.parse("2019-06-23T13:02:55Z"), o1);
orderRepository.save(o1);
paymentRepository.save(p1);
它工作的唯一方法如下:
Order o1 = new Order(null, Instant.parse("2019-06-20T19:53:07Z"));
Payment p1 = new Payment(null, Instant.parse("2019-06-23T13:02:55Z"), o1);
o1.setPayment(p1);
orderRepository.save(o1);
paymentRepository.save(p1);
我想了解为什么只有最后的方法有效。在一个一对一的关联中,我不必在保存之前就设定双向关联才能工作。我错过了独立实体行为这种情况的什么?谢谢。
,因为我们必须像您使用的那样为父型实体设置子实体 o1.setPayment(p1);
无需将 id作为null ,因为它将是 @GeneratedValue
。您可能必须为其创建适当的构造函数。
当您使用cascade=CascadeType.ALL
时,您可以保存父母和孩子如下无需使用两个实体
//save Parent-Child at same
@PostMapping(value = "/onetoone")
public String OneToOne(@RequestBody ParentOne parent)
{
ChildOne childOne = parent.getChildOne();
childOne.setParentOne(parent);
parent.setChildOne(childOne);
parentOneRepository.save(parent);
return "saved";
/*{
"parentName":"Parent Name",
"childOne":{
"childName":"Child Name"
}
}*/
}
讨论
尝试这个,
Order o1 = new Order(null, Instant.parse("2019-06-20T19:53:07Z"));
Payment p1 = new Payment(null, Instant.parse("2019-06-23T13:02:55Z"), o1);
o1.setPayment(p1);
orderRepository.save(o1);
不需要保存方法进行付款。因为每当保存订单时,您都会使用@OneToOne(cascade=CascadeType.ALL, mappedBy="order")
的级联类型,然后也保存。