可以安全地假设 @Transient 使 JPA 提供者始终保留带注释的字段吗?

Is it safe to assume that @Transient makes JPA provider to leave annotated field always intact?

受到 的启发,我开始更详细地研究JPA 的@Transient 注释的功能。在提到的答案中:

One merge or refresh too many and your transient field value is lost.

然后我看过的每份文档都说大致相同:

Fields annotated with @Transient are not persisted

我没有发现完全忽略这样一个字段,我意识到我没有明确的证据,但不知何故,我总是隐含地理解它,就像 @Transient 注释字段被 JPA 忽略(供应商).

举个例子,如果这样的字段从未保存在数据库中(我的意思是保存在 JPA 上下文中),是否有必要从数据库中获取该字段。为此,我猜有 @Column(insertable=false, updatable=false)?

所以我真的应该意识到 mergerefresh 对于一个实体,无论是否在管理时操作,使某些@Transient字段的值发生变化?

如果是,这种情况的简单示例是什么?

  • 我想考虑3种情况

    • 在非托管实体上调用 merge,其中非托管实体填充了瞬态字段
    • 在受管实体上调用 merge,其中受管实体在成为受管后用瞬态字段填充
    • 在托管实体上调用刷新,其中托管实体在成为托管实体后填充了一个瞬态字段。无论如何都不允许在非托管实体上调用 refresh
  • 在非托管实体上调用 merge,其中非托管实体填充了瞬态字段

    • 可以免费实现 return 一个新实体,这意味着瞬态字段丢失了。我已经用休眠验证了行为,它失去了价值。即使某些实现使其不会失去价值,我也不会依赖它,因为合并对 return 新实体是免费的。
  • 在受管实体上调用 merge,其中受管实体在成为受管后用瞬态字段填充

    • 它是一个托管实体,因此 JPA 需要提供 repeatable read。因此,即使您执行 merge,JPA 也必须满足这两个保证,即您对托管实体的对象引用不能更改,并且该对象应包含来自 db 的最新值。 JPA 没有理由触及您的 transient 字段。它只会更新任何在数据库中被管理和更新的字段。我已验证此行为并按预期运行。
  • 在托管实体上调用刷新,其中托管实体在成为托管实体后填充了一个临时字段

    • 与合并受管实体的参数相同。 JPa 不会丢失您的瞬态值。我已验证此行为并按预期运行。

总结

  • 调用合并时,您将丢失非托管实体的临时值。

GitRepo