最近在处理一些数据多语言的支持技术。因为以前的系统没有对多语言支持和持久层采用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.“。 session
通过查找信息,发现了Hibernate的拦截器(interceptor)。使用过struts的人对拦截器这个概念并不陌生。Hibernate也的确用它在作相似的事情。在interceptor中有这样的一个接口,preFlush(Called before a flush)。在这个接口中,咱们能够得到flush下的一个对象集的iterator。这个时候,我对须要国际化的对象,建立一个接口I18nEntity,使须要特殊处理的entity实现该接口。在preFlush实现中,我监听I18nEntity下的对象,并完成国际化数据信息的merge。 spa
对于更新操做的合并已经出现了,然而问题这么解决下来,就很难让人以为编程中解决一个BUG的成就感了。新的问题是:在load以后,关闭session中,即便没有保存信息,即便事物设置为readonly,在openSessionInView中设置为MANUAL/NERVER也会使得出现detach的数据信息,依旧被merge了! .net
这个时候,我查到了又一个新的东西,就是事件。我加入了我又一个元素,SaveOrUpdateEventListener。我经过这个接口的实现,监听update信息。而对于事件中,Hibernate不容许你修改entity的对象信息,只能读取,即一种readonly模式。 日志
因而,在解决这个问题的时候,我被迫使用了ThreadLocal。在监听到update事件的时候,我对当前更新的对象记录了一条更新记录。这样在执行拦截器的时候,调用方法时,经过验证是否存在更新记录,来执行这个数据对象的merge操做。当完成merge后,我将这条更新记录移除,来保证不会重复merge! 对象
------------------------------------------------------------------------------------------------ blog
在写日志的时候,我从新查看了Interceptor接口,又发现了onSave和onDirtyFlush两个接口,也许也能有相似的功能任务。我的以为本身的解决办法笨拙了。 接口
对于Interceptor中onSave解决方法可参考:http://blog.csdn.net/pengchua/article/details/4398968 事件