获取“java.lang.IllegalArgumentException:删除分离的实例”

问题描述 投票:0回答:1

我正在尝试使用实体管理器删除实体。以下是我的课程:

实体类

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "GrandParent", schema = "testDbo")
public class GrandParent implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    @Column(name = "LADDER_SEQUENCE_ID", unique = true, nullable = false)
    protected UUID ladderSequenceId;

    @Column(name = "LADDER_ID", unique = true, nullable = false)
    protected String ladderId;
    @Column(name = "LADDER_NAME")
    protected String ladderName;
    @Column(name = "LADDER_ACCOUNT_NBR")
    protected String ladderAccountNumber;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "ladder")
    private List<Parent> ladderRungs;
}

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "Parent", schema = "testDbo")
public class Parent implements Serializable{
    @Serial
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    @Column(name = "LADDER_RUNG_SEQUENCE_ID", unique = true, nullable = false)
    private UUID ladderRungSequenceId;
    @Column(name = "LADDER_ID")
    protected String ladderId;
    @Column(name = "LADDER_RUNG_NBR")
    protected Integer ladderRungNumber;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "LADDER_SEQUENCE_ID", nullable = false)
    GrandParent ladder;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "rung")
    protected List<Child> rungPositions;
}

@Data
@Entity
@Table(name = "Child" , schema = "testDbo")
public class Child implements Serializable{
    @Serial
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    @Column(name = "LADDER_POSITION_ID", unique = true, nullable = false)
    protected UUID ladderPositionId;

    @Column(name = "LADDER_RUNG_NBR")
    protected Integer ladderRungNumber;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="LADDER_RUNG_SEQUENCE_ID", referencedColumnName = "LADDER_RUNG_SEQUENCE_ID")
    protected Parent rung;
}

存储库类

@Repository
public interface GrandParentRepository extends JpaRepository<GrandParent, UUID> {
    GrandParent findByLadderIdAndLadderAccountNumber(String ladderId, String accountNumber);
}

数据库服务代码:

@Autowired
private EntityManagerFactory entityManagerFactory;

EntityManager em;
public void ladderDBStartTransaction(){
    em = entityManagerFactory.createEntityManager();
    em.getTransaction().begin();
}

public void deleteGrandParent(String ladderId, String accountNumber){
        GrandParent grandParent = grandParentRepository.findByLadderIdAndLadderAccountNumber(ladderId, accountNumber);
        log.info("GrandParent Entity : {}", grandParent);
        try{
            em.remove(grandParent);
            em.getTransaction().commit();
        }catch (Exception ex){
            em.getTransaction().rollback();
        }finally {
            em.close();
        }
    }

申请代码:

ladderDBService.ladderDBStartTransaction();
ladderDBService.deleteGrandParent(newLadderId, accountNumber);

日志和异常

GrandParent Entity : 
 GrandParent{ladderSequenceId=203f0264-7ea7-4aa3-875c-282d161469fd, ladderId='00193', ladderName='TestLadder', ladderAccountNumber='X04977780', ladderRungs=[
 Parent{ladderRungSequenceId=70fb2731-367c-4ddc-886b-5a7cb73503e0, ladderId='00193', ladderRungNumber=3, rungPositions=[
 Child{ladderPositionId=77baba51-be06-47ff-9568-1dd09bc10075, ladderRungNumber=3}]}, 
 Parent{ladderRungSequenceId=339ff84f-f6a0-413d-9056-a1827783efde, ladderId='00193', ladderRungNumber=1, rungPositions=[
 Child{ladderPositionId=c3ee56e8-d8da-4f4c-b7e7-0ddc600d38b3, ladderRungNumber=1}]}, 
 Parent{ladderRungSequenceId=8603c6de-20ba-4923-afd4-4381b4935ba6, ladderId='00193', ladderRungNumber=4, rungPositions=[
 Child{ladderPositionId=84e10edc-b688-4265-8bdd-8bb2377be55b, ladderRungNumber=4}]}, 
 Parent{ladderRungSequenceId=fcd2dca9-484e-4e14-9b7b-36979e4d766b, ladderId='00193', ladderRungNumber=2, rungPositions=[
 Child{ladderPositionId=088cd0f4-a72c-4366-a70c-d3d8967e5b2e, ladderRungNumber=2}, 
 Child{ladderPositionId=f6750041-56d3-4629-aa29-cca08186ec10, ladderRungNumber=2}]}]}
java.lang.IllegalArgumentException: Removing a detached instance com.model.entities.GrandParent#203f0264-7ea7-4aa3-875c-282d161469fd
    at org.hibernate.event.internal.DefaultDeleteEventListener.disallowDeletionOfDetached(DefaultDeleteEventListener.java:191)
    at org.hibernate.event.internal.DefaultDeleteEventListener.performDetachedEntityDeletionCheck(DefaultDeleteEventListener.java:179)
    at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:106)
    at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:74)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
    at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:943)

我已经浏览了一些关于这个问题的线索,这些线索已经发布在网站上。另外,通过谷歌。看来在删除实体之前,我必须先找到它。因此,尝试遵循相同的步骤。根据日志,在删除之前从数据库检索实体。

问题 我在这里做错了什么?

spring-boot jpa spring-data-jpa entitymanager
1个回答
0
投票

当您尝试删除已与持久化上下文分离的实体时,会抛出

Removing a detached instance exception

在您的情况下,正在使用 grandParentRepository.findByLadderIdAndLadderAccountNumber 中创建的单独 EntityManager 实例检索 grandParent 实体。

这个EntityManager实例与ladderDBStartTransaction中创建的实例不同。因此,当您尝试删除实体时,它会与ladderDBStartTransaction中创建的EntityManager分离,并引发异常。

要删除实体,您需要将其合并到持久化上下文中。这将使实体由 EntityManager 管理,然后您可以删除它。

public void deleteGrandParent(String ladderId, String accountNumber){
    GrandParent grandParent = grandParentRepository.findByLadderIdAndLadderAccountNumber(ladderId, accountNumber);
    log.info("GrandParent Entity : {}", grandParent);
    try{
        em.remove(em.contains(grandParent) ? grandParent : em.merge(grandParent));
        em.getTransaction().commit();
    }catch (Exception ex){
        em.getTransaction().rollback();
    }finally {
        em.close();
    }
}

参考文档

© www.soinside.com 2019 - 2024. All rights reserved.