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

Is it ok to reference a JPA entity that has been deleted?

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

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

所以我的逻辑最终可以删除这个实体(调用EntityManger.remove方法),然后我想将所做的事情写入日志文件,包括otherTable[=的引用成员17=] 对象。这是 JPA 中允许的操作吗?

规范中的相关行是:

After an entity has been removed, its state (except for generated state) will be that of the entity at the point at which the remove operation was called.

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

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

Is this a permitted operation in JPA?

是的。

当您调用 remove 时,JPA(底层 JPA 提供程序)所做的只是 "mark" 该实例应该是 deleted/removed。但是即使事务被提交(并且实例从数据库中删除)与否,实例对象仍然保持不变。其属性的任何更改都取决于您的操作。

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

请注意,在其他情况下,如果您 refresh 在登录您想要的实体之前就搞砸了。

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

Synchronization to the database does not involve a refresh of any managed entities unless the refresh operation is explicitly invoked on those entities or cascaded to them as a result of the specification of the cascade=REFRESH or cascade=ALL annotation element value