java - 我很确定 Finalize 对于后来的 JVM 来说仍然是个坏消息——还有其他选择吗?

标签 java orm finalize finalization

我想实现一个 ORM 风格的系统,当调用者无法再访问 POJO 时,该系统可以保存对 POJO 的更新。

我认为引用类可以做到这一点,但它们似乎只在对象被清除后才将引用加入队列(我希望是在它们能够被收集时),所以一旦将 .get() 方法加入队列将始终返回 null。

我可以使用终结器,但上次我检查这些是有问题的(不能保证立即运行或根本运行)——我相信终结器和 runShutdownHook() 的组合会起作用,但这会进入相当沼泽的领域。

除了强制性的“让调用者在完成后调用 .save() ”之外,还有其他我没有想到的路径吗?

最佳答案

您是否只是想避免在修改的每个 POJO 上调用 save()

这可以使用持久 session 对象可靠地完成,如下所示:

  1. 打开一个新的 session 对象。
  2. 通过 session 对象加载对象。 session 对象维护对其加载的所有对象的引用。
  3. 对加载的对象进行任何更改。没有必要对更新的对象调用保存方法。
  4. 关闭 session 对象。 session 保存其所有对象。它甚至可能足够花哨,保留干净加载数据的副本,将其所有对象与干净数据进行比较,并仅保存已修改的对象。

如果您不想通过代码传递 session 对象,您可以使用工作单元模式更进一步,将 session 对象关联到当前线程:

  1. 开始一个工作单元。这会在幕后创建一个 session 对象并将其与当前线程关联起来。
  2. 加载对象。每当加载一个对象时,您的 ORM 都会自动将其与基于当前线程的 session 对象关联起来。
  3. 对加载的对象进行任何更改。没有必要对更新的对象调用保存方法。
  4. 完成工作单元。这将关闭 session 对象,保存所有对象。

这解决了基于可达性的解决方案的几个问题:

  • 您不依赖于不确定性垃圾收集,它的运行间隔可能很长,或者根本不运行。
  • 在一次操作中修改的所有对象都保存在一起。如果您依赖可达性,则在同一操作中修改的不同对象可能在不同时间变得不可达,这意味着您的修改可以零散地保存到数据库中。
  • 回滚要容易得多——只需为您的 session 对象提供一个 rollback() 方法即可。使用可达性解决方案,如果操作失败,您需要记住在每个修改的 POJO 上调用 rollback(),这实际上与您原来的问题相同。

也许请参阅http://nhibernate.info/doc/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.html或者研究工作单元模式并模仿其中的一些想法。

关于java - 我很确定 Finalize 对于后来的 JVM 来说仍然是个坏消息——还有其他选择吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5359367/

相关文章:

对基于声明的模型使用多值插入时,不会为每一行单独调用 Python 端默认值

database - 函数式编程和数据库交互的最佳实践是什么?

java - 定义 : Unfinalized versus finalizable object

java - 为什么不调用 finalize()?

java - 发布类加载器时,什么时候对单例调用 finalize?

java - 为什么在 Java 中使用 StringBuffer 而不是字符串连接运算符

.net - 您使用的 ORM 框架的最佳功能是什么

java - 至少包含一个数字的字符串的正则表达式

java - 基于 Gradle 的子项目在构建期间抛出 `Could not find or load main class worker.org.gradle.process.internal.worker.GradleWorkerMain`

java - 如何为 Java Web 应用程序创建 JNLP 文件?