春季数据JPA:一对一的实例化问题:PersistEntObjectException:传递的独立实体被持续存在



我正在写一个简单的订单付款一对一关联:

订购类相关代码:

@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存储库来播种我的测试数据库,但是如果我尝试以下代码,我会得到一个PersistentObjectExceptiondetached 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((
//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")的级联类型,然后也保存。

最新更新