最近在處理一些數據多語言的支持技術。因爲以前的系統沒有對多語言支持和持久層採用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 事件