我想实现一个 ORM 风格的系统,当调用者无法再访问 POJO 时,该系统可以保存对 POJO 的更新。
我认为引用类可以做到这一点,但它们似乎只在对象被清除后才将引用加入队列(我希望是在它们能够被收集时),所以一旦将 .get() 方法加入队列将始终返回 null。
我可以使用终结器,但上次我检查这些是有问题的(不能保证立即运行或根本运行)——我相信终结器和 runShutdownHook() 的组合会起作用,但这会进入相当沼泽的领域。
除了强制性的“让调用者在完成后调用 .save() ”之外,还有其他我没有想到的路径吗?
最佳答案
您是否只是想避免在修改的每个 POJO 上调用 save()
?
这可以使用持久 session 对象可靠地完成,如下所示:
- 打开一个新的 session 对象。
- 通过 session 对象加载对象。 session 对象维护对其加载的所有对象的引用。
- 对加载的对象进行任何更改。没有必要对更新的对象调用保存方法。
- 关闭 session 对象。 session 保存其所有对象。它甚至可能足够花哨,保留干净加载数据的副本,将其所有对象与干净数据进行比较,并仅保存已修改的对象。
如果您不想通过代码传递 session 对象,您可以使用工作单元模式更进一步,将 session 对象关联到当前线程:
- 开始一个工作单元。这会在幕后创建一个 session 对象并将其与当前线程关联起来。
- 加载对象。每当加载一个对象时,您的 ORM 都会自动将其与基于当前线程的 session 对象关联起来。
- 对加载的对象进行任何更改。没有必要对更新的对象调用保存方法。
- 完成工作单元。这将关闭 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/