简体   繁体   English

保存时传递的分离实体持续存在

[英]Detached entity passed to persist when saving

I have some codes, but it gets a error at personRepository.save(person2), no need to fix this but just explaining for me why this throws: detached entity passed to persist.我有一些代码,但它在 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
      }

I understand you did not annotate your test with @Transactional - in that case scenario spring is creating transaction for you to perform the "save" as you call it.我了解您没有使用 @Transactional 注释您的测试 - 在这种情况下,spring 正在为您创建事务以执行您所称的“保存”。 More on that here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions更多信息: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions

In 1st case you are having "new" objects (without ID, and unmanaged by JPA provider), and you did specify cascading so JPA provider knows how to save it in 1 transaction.在第一种情况下,您拥有“新”对象(没有 ID,并且不受 JPA 提供者管理),并且您确实指定了级联,因此 JPA 提供者知道如何将其保存在 1 个事务中。

In 2nd case, you are adding wallet that is already managed object, but without transaction.在第 2 种情况下,您正在添加已经管理 object 但没有交易的钱包。

You either need to do it all in @Transactional scope (annotate your test), or if you pass object from "outside" of transaction (that's yr scenario), again...you need to have a transaction - so you need to start it and call merge() on the object that comes from outside of it.您要么需要在@Transactional scope 中完成所有操作(注释您的测试),要么如果您从事务的“外部”通过 object(那是一年的情况),再次......你需要有一个事务 - 所以你需要开始它并在来自外部的 object 上调用 merge()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM