删除

时间:2016-02-19 05:33:56

标签: eclipselink

我正在将EclipseLink与容器管理的实体管理器一起使用。我一直在尝试确定有时在删除期间看到的QueryException的原因。例外描述是:

  

对象MySubEntity不是来自此UnitOfWork对象空间,而是来自父会话。

以下是该模型的简化描述:

@Entity
public class MyEntity
{
    @OneToMany(targetEntity = MySubEntity.class,
               cascade = { CascadeType.ALL },
               orphanRemoval = true)
    @JoinColumn(name = "PARENT_ID")
    private List<MySubEntity> subEntities;
}

我发现以下成功:

MyEntity firstEntity = entityManager.find(MyEntity.class, firstKey);
MyEntity secondEntity = entityManager.find(MyEntity.class, secondKey);

entityManager.remove(firstEntity);
//entityManager.flush();
entityManager.remove(secondEntity);

但如果我取消注释flush,则会因QueryException而失败。

显示的代码仅用于验证问题,实际上删除操作并非如此接近,并且读取查询会隐式触发刷新。

我使用EclipseLink 2.5.1和2.6.2验证了这种行为。这是一个已知的EclipseLink错误吗?我找不到记录的文件。这是预期的行为吗?

我尝试在第一次删除之前和之后调用UnitOfWork.validateObjectSpace()但在两种情况下validateObjectSpace()都成功。

1 个答案:

答案 0 :(得分:1)

我在自己的工作中遇到了这个问题,在寻求帮助时我偶然发现了这个问题。我不能肯定地说我的问题是否相同,但它非常相似。我的目标是帮助那些发现这一点的人。

首先让我解释一下我的模型与问题相比的细微差别。我不认为这些差异应该是一个很大的问题,但是如果我错了(或者它将来会帮助某人),我会把它们包括在内。 MyEntity和MySubEntity之间的关系不是列表,而是一对一的。相应地命名。

@Entity
public class MyEntity
{
    @OneToOne(cascade = { CascadeType.REMOVE, CascadeType.PERSIST }, orphanRemoval = true,fetch = FetchType.EAGER)
    @JoinColumn(name = "SUB_ENTITY_KEY")
    private MySubEntity subEntity;
}

执行:

  • 我的执行与问题基本相同。使用实体管理器删除多个实体并刷新。我的问题不需要刷新(因为实体管理器最终将自动刷新)但是它确实使其更快地失败。

预期结果:

  • 我希望删除firstEntitysecondEntity以及它们各自的subEntity对象也应该被删除,因为它们现在是孤儿。

实际结果:

  • 问题中描述的UnitOfWork异常。我发现当删除多个MyEntity对象时,EclipseLink无法在删除时正确处理关系。这似乎并不是在每种情况下都会发生,但如果您能够产生混淆EclipseLink的情况,它将始终如一地产生此异常。

解决方案:

  • 在删除之前手动取消MyEntity和subEntity的关联。这可以通过myEntity1.setSubEntity(null);
  • 来完成
  • 更好的是将其添加到MyEntity的预删除中,以便它自动解除关联。

示例:

@PreRemove
public void onRemove() {
    this.subEntity= null;
}

平台信息:

  • EclipseLink v2.4.3
  • Oracle JRE 1.7.0_79
  • Weblogic 12.1.2