为什么在首先合并实体时,我会将已删除的实例传递给合并

时间:2014-10-15 17:46:49

标签: java jpa merge entitymanager

我相信我想删除的实体是一个管理实体。但是,无论如何,为什么合并它然后删除它给我以下错误:

已删除的实例已合并

有人在stackoverflow上说如果它是一个托管实体,那么应该忽略该合并。那为什么不被忽视呢?

我希望删除它的方式如下:

TrialUser mergedEntity = em.merge(tu);
em.remove(mergedEntity);

但这个错误,但如果我摆脱第一行它似乎工作正常。但我想要另一种方式,因为这与代码的其余部分是一致的。

编辑:

@PersistenceContext(unitName = "UnitName")
protected EntityManager entityManager;

     @Table(name="TRIAL_USER")

     @Id
     private BigDecimal id;

     @ManyToOne(cascade= {CascadeType.ALL }, fetch=FetchType.EAGER)
     @JoinColumn(name="TRIAL_USER_CLASS_ID3")
     private TrialUserElement trialUserElement3;

@ManyToOne(cascade= {CascadeType.ALL }, fetch=FetchType.EAGER)
@JoinColumn(name="TRIAL_USER_CLASS_ID1")
private TrialUserElement trialUserElement1;


@ManyToOne(cascade= {CascadeType.ALL }, fetch=FetchType.EAGER)
@JoinColumn(name="TRIAL_USER_CLASS_ID2")
private TrialUserElement trialUserElement2;

3 个答案:

答案 0 :(得分:9)

当您在事务中运行某些代码时,当您在方法结束时提交时,可能会出现此错误。 在使用

注释的方法或类中使用spring时
@Transactional

这是因为您首先删除了对象(未提交),然后尝试更新它。

此代码将生成异常:

    @Transactional
    myethod(){
      dao.delete(myObject);
      myObject.setProperty("some value");
      dao.save();  
    }

为避免错误,您不应删除,然后保存在同一事务中。

答案 1 :(得分:2)

由于我无法运行您的代码,所以这是一个黑暗的镜头,这些类型的问题可能会变得有点复杂。但请放心,合并然后删除应该没问题。我怀疑它可能与您的多个关联实体有关。

在事务提交时,删除被级联到链接的实体。

即使合并对于您的父实体来说是多余的,我认为合并正在级联到已删除的子实体,因此也是例外。

尝试更改级联规则 - 将其拉回CascadeType.MERGE(对于所有三个)并查看是否仍然获得异常。或者更改为CascadeType.DELETE,这将阻止必要的合并级联。

答案 2 :(得分:-3)

JPA SPEC说:

  

3.2.7.1合并分离的实体状态

     
    

如果X是已删除的实体实例,则将抛出IllegalArgumentException     合并操作(或事务提交将失败)。

  

这就是为什么你不能合并一个被删除的实体。