假设@Transient使JPA提供者始终保持注释字段不变是否安全



受到这个答案的启发,我开始更详细地研究JPA的@Transient注释的功能。上面提到的答案是:

一次合并或刷新次数过多,您的瞬态字段值将丢失。

然后我浏览过的每一份文档都大致相同:

用@Transient注释的字段未持久化

我没有发现完全忽略这样一个字段,我意识到我没有明确的证据,但不知何故,我一直像@JPA(提供者(忽略了瞬态注释字段一样隐含地理解它。

例如,如果从未在数据库中持久化过这样一个字段,那么从数据库中获取它是否有意义?我的意思是持久化在JPA上下文中。我想有@Column(insertable=false,updateable=false(?

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

如果是的话,这种情况的一个简单例子是什么?

  • 我想考虑3种情况

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

    • 实现可以自由返回一个新实体,这意味着瞬态字段丢失。我已经用hibernate验证了这种行为,它失去了价值。即使某些实现使它不会失去价值,我也不会依赖它,因为合并可以自由返回新实体
  • 在托管实体上调用merge,其中托管实体在成为托管实体后会填充一个临时字段

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

    • 与合并托管实体的参数相同。JPa不能丢失您的瞬时值。我已经证实了这一行为,并按预期行事

摘要

  • 调用merge时,将丢失非托管实体的瞬态值

GitRepo

  • https://github.com/kavi-kanap/stackoverflow-63003677.只需将spring-boot项目作为maven项目导入并启动应用程序。它将运行以上3个场景,并将结果打印到控制台

最新更新