可以引用已删除的JPA实体吗?

时间:2015-08-09 01:50:04

标签: jpa eclipselink jpa-2.0

我有一个链接到其他人的JPA实体 - 类似这样:

@Entity
class LinkRec implements Serializable {
    ...
   @OneToOne
   private OtherEntity otherTable;
     ...
}

所以我的逻辑最终可以删除这个实体(调用EntityManger.remove方法),然后我想写一个日志文件做了什么,包括 otherTable 对象的引用成员。这是JPA允许的操作吗?

2 个答案:

答案 0 :(得分:3)

  

这是JPA允许的操作吗?

当您调用remove时,JPA(底层JPA提供程序)执行的操作只是“标记”该实例应该被删除/删除。但即使事务已提交(并且实例已从数据库中删除),实例对象仍保持不变。对其属性的任何更改都取决于您的操作。

由于您将实体标记为已删除,因此您无法从数据库刷新实例的状态(调用EntityManager.refersh方法)。您将获得IllegalArgumentException

请注意,在其他情况下,如果您在登录之前refresh实体,您可能会搞砸了。

我引用了JPA规范中的文字(参见Synchronization to the Database部分),可以帮助您理解“JPA”行为

  

与数据库的同步不涉及刷新任何托管实体,除非由于cascade = REFRESH或cascade = ALL注释元素值的规范而在这些实体上显式调用刷新操作或级联刷新操作

答案 1 :(得分:1)

规范中的相关行是:

  

删除实体后,其状态(生成状态除外)将是调用删除操作时实体的状态。

由于这是我在规范中可以找到的所有内容,我会说它可能因实现而异。在我看来,这使你想要做的事情变得危险。它可以在一个JPA实现中工作,而不是在另一个版本中工作,或者在一个版本中工作而不是在升级中工作。

如果我不得不猜测实现,我会说@OneToOne对象可能会正常工作。我担心的是像@OneToMany这样的事情。例如,在Hibernate的情况下:这个集合可能是水合的并且在内存中,但它也可能指向代理。如果它是一个代理并且您调用getter,它将检查数据库中的集合并且无法加载它,因为该对象已经消失。