首页 > 解决方案 > 保存时传递的分离实体持续存在

问题描述

我有一些代码,但它在 personRepository.save(person2) 处出现错误,无需解决此问题,只是为我解释为什么会抛出:分离的实体传递给坚持。

  @Entity
    public class Person {

        @Id
        @GeneratedValue
        @Column(name = "id")
        private Long id;

        @Column(name = "name")
        private String name;

        @Column(name = "wallet_id", insertable = false, updatable = false)
        private Long wallet_id;

        @ManyToOne  (fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JoinColumn(name = "wallet_id",referencedColumnName = "id", insertable = true, updatable = true )
        private Wallet wallet;
    }




    public void testSave(String name) {
            Wallet walletNewNoHaveInDB = new Wallet(); // Generated id.

            Person person = new Person(); // Generated id.
            person.setName(name);
            person.setWallet(walletNewNoHaveInDB);
            personRepository.save(person); // This is OK and inserted into DB both(wallet , person).

            Person person2 = new Person(); // Generated id.
            person2.setName(name);
            person2.setWallet(walletNewNoHaveInDB);
            personRepository.save(person2); /// detached entity passed to persist
      }

标签: javahibernatejpaentitymanager

解决方案


我了解您没有使用 @Transactional 注释您的测试 - 在这种情况下,spring 正在为您创建事务以执行您所称的“保存”。更多信息在这里:https ://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

在第一种情况下,您拥有“新”对象(没有 ID,并且不受 JPA 提供者管理),并且您确实指定了级联,因此 JPA 提供者知道如何将其保存在 1 个事务中。

在第二种情况下,您添加的钱包已经是托管对象,但没有交易。

您要么需要在@Transactional 范围内完成所有操作(注释您的测试),要么如果您从事务的“外部”传递对象(这是您的场景),再次......您需要有一个事务 - 所以您需要开始它并在来自它外部的对象上调用 merge() 。


推荐阅读