保存时传递给持久化的分离实体

Detached entity passed to persist when saving

我有一些代码,但它在 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
      }

我知道你没有用@Transactional 注释你的测试 - 在这种情况下 spring 正在为你创建事务以执行你调用的 "save"。更多相关信息:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

在第一种情况下,您有 "new" 个对象(没有 ID,并且不受 JPA 提供程序管理),并且您确实指定了级联,因此 JPA 提供程序知道如何在 1 个事务中保存它。

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

您要么需要在 @Transactional 范围内完成所有操作(注释您的测试),要么如果您从交易的 "outside" 传递对象(那是您的场景),再次......您需要有一个事务 - 因此您需要启动它并在来自它外部的对象上调用 merge()。