可以安全地假设 @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)?
所以我真的应该意识到 merge 或 refresh 对于一个实体,无论是否在管理时操作,使某些@Transient
字段的值发生变化?
如果是,这种情况的简单示例是什么?
我想考虑3种情况
- 在非托管实体上调用
merge
,其中非托管实体填充了瞬态字段
- 在受管实体上调用
merge
,其中受管实体在成为受管后用瞬态字段填充
- 在托管实体上调用刷新,其中托管实体在成为托管实体后填充了一个瞬态字段。无论如何都不允许在非托管实体上调用
refresh
在非托管实体上调用 merge
,其中非托管实体填充了瞬态字段。
- 可以免费实现 return 一个新实体,这意味着瞬态字段丢失了。我已经用休眠验证了行为,它失去了价值。即使某些实现使其不会失去价值,我也不会依赖它,因为合并对 return 新实体是免费的。
在受管实体上调用 merge
,其中受管实体在成为受管后用瞬态字段填充。
- 它是一个托管实体,因此 JPA 需要提供
repeatable read
。因此,即使您执行 merge
,JPA 也必须满足这两个保证,即您对托管实体的对象引用不能更改,并且该对象应包含来自 db 的最新值。 JPA 没有理由触及您的 transient 字段。它只会更新任何在数据库中被管理和更新的字段。我已验证此行为并按预期运行。
在托管实体上调用刷新,其中托管实体在成为托管实体后填充了一个临时字段。
- 与合并受管实体的参数相同。 JPa 不会丢失您的瞬态值。我已验证此行为并按预期运行。
总结
- 调用合并时,您将丢失非托管实体的临时值。
GitRepo
- https://github.com/kavi-kanap/Whosebug-63003677。只需将 spring 引导项目导入为 Maven 项目并启动应用程序。它将 运行 以上 3 个场景并将结果打印到控制台
受到@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)?
所以我真的应该意识到 merge 或 refresh 对于一个实体,无论是否在管理时操作,使某些@Transient
字段的值发生变化?
如果是,这种情况的简单示例是什么?
我想考虑3种情况
- 在非托管实体上调用
merge
,其中非托管实体填充了瞬态字段 - 在受管实体上调用
merge
,其中受管实体在成为受管后用瞬态字段填充 - 在托管实体上调用刷新,其中托管实体在成为托管实体后填充了一个瞬态字段。无论如何都不允许在非托管实体上调用
refresh
- 在非托管实体上调用
在非托管实体上调用
merge
,其中非托管实体填充了瞬态字段。- 可以免费实现 return 一个新实体,这意味着瞬态字段丢失了。我已经用休眠验证了行为,它失去了价值。即使某些实现使其不会失去价值,我也不会依赖它,因为合并对 return 新实体是免费的。
在受管实体上调用
merge
,其中受管实体在成为受管后用瞬态字段填充。- 它是一个托管实体,因此 JPA 需要提供
repeatable read
。因此,即使您执行merge
,JPA 也必须满足这两个保证,即您对托管实体的对象引用不能更改,并且该对象应包含来自 db 的最新值。 JPA 没有理由触及您的 transient 字段。它只会更新任何在数据库中被管理和更新的字段。我已验证此行为并按预期运行。
- 它是一个托管实体,因此 JPA 需要提供
在托管实体上调用刷新,其中托管实体在成为托管实体后填充了一个临时字段。
- 与合并受管实体的参数相同。 JPa 不会丢失您的瞬态值。我已验证此行为并按预期运行。
总结
- 调用合并时,您将丢失非托管实体的临时值。
GitRepo
- https://github.com/kavi-kanap/Whosebug-63003677。只需将 spring 引导项目导入为 Maven 项目并启动应用程序。它将 运行 以上 3 个场景并将结果打印到控制台