Hibernate下onUpdate处理机制

最近在处理一些数据多语言的支持技术。由于之前的系统没有对多语言支持和持久层采用Hibernate实现,所以考虑通过lifecycle接口,在对象持久化时,将多语言字段信息进行语言数据拼接,然后再进行保存。在对象加载时,先根据语言环境从数据信息中加载当前语言环境下的数据信息。

在实现中,问题出现了~!对于onSave,onLoad接口,都是很顺利解决了需求上问题。然而,onUpdate的接口,却没有更好的发挥它的作用,即有的时候update,不能将数据与其他语言数据完成merge,而是覆盖了原数据,导致了数据信息丢失。看了Hibernate的文档,onUpdate接口上有如此注释,”This method is not called every time the object's state is persisted during a flush.“。

经过查找信息,发现了Hibernate的拦截器(interceptor)。使用过struts的人对拦截器这个概念并不陌生。Hibernate也的确用它在做类似的事情。在interceptor中有这样的一个接口,preFlush(Called before a flush)。在这个接口中,我们可以获得flush下的一个对象集的iterator。这个时候,我对需要国际化的对象,创建一个接口I18nEntity,使需要特殊处理的entity实现该接口。在preFlush实现中,我监听I18nEntity下的对象,并完成国际化数据信息的merge。

对于更新操作的合并已经出现了,然而问题这么解决下来,就很难让人觉得编程中解决一个BUG的成就感了。新的问题是:在load之后,关闭session中,即使没有保存信息,即使事物设置为readonly,在openSessionInView中设置为MANUAL/NERVER也会使得出现detach的数据信息,依旧被merge了!

这个时候,我查到了又一个新的东西,就是事件。我加入了我又一个元素,SaveOrUpdateEventListener。我通过这个接口的实现,监听update信息。而对于事件中,Hibernate不允许你修改entity的对象信息,只能读取,即一种readonly模式。

于是,在解决这个问题的时候,我被迫使用了ThreadLocal。在监听到update事件的时候,我对当前更新的对象记录了一条更新记录。这样在执行拦截器的时候,调用方法时,通过验证是否存在更新记录,来执行这个数据对象的merge操作。当完成merge后,我将这条更新记录移除,来保证不会重复merge!

------------------------------------------------------------------------------------------------

在写日志的时候,我重新查看了Interceptor接口,又发现了onSave和onDirtyFlush两个接口,也许也能有类似的功能任务。个人觉得自己的解决办法笨拙了。

对于Interceptor中onSave解决方法可参考:http://blog.csdn.net/pengchua/article/details/4398968

你可能感兴趣的:(Interceptor,事件监听,lifecycle,onUpdate)