2015-11-05 27 views
0

我正在運行Grails 2.4.5和Hibernate 3.6.10的應用程序。 有一個具有子PersistentMap的域對象。該地圖存儲4 鍵值對,其中值始終是字符串。Hibernate PersistentMap返回錯誤值

在我們的開發和測試環境中,一切正常,然後偶爾 持久映射開始爲鍵或值返回「1」。 父域對象中的其他值很好。通過在數據庫中直接更新地圖 的地圖記錄之一,解決了問題 。這讓我覺得它是一種緩存問題, ,但我還沒有能夠在本地環境中重新創建它。

下面的數據庫是MySQL。

以下不是實際的代碼,但代表結構。

class MyDomain { 

    static belongsTo = [owner: Owner] 

    static hasMany = [relatedDomains: RelatedDomain] 

    Set relatedDomains = [] 

    Map flags = [:] 

    String simpleItem 

    String anotherItem 

    static constraints = { 
     owner(nullable: true) 
     relatedDomains(nullable: true) 
     flags(nullable: true) 
     simpleItem(nullable: true) 
     anotherItem(nullable: true) 
    } 
} 

這導致情侶表(忽略RelatedDomain和所有者)的:

mydomain table 
| id | version |owner_id|simple_item|another_item | 
|-------|-----------|--------|-----------|-------------| 
| 1 | 1  | 1 | A value |Another value| 

mydomain_flags table 

|flags| flags_ids | flags_elt | 
|-----|-----------|-------------| 
| 1 | KEY_ONE | VALUE_ONE | 
| 1 | KEY_TWO | VALUE_TWO | 
| 1 | KEY_THREE | VALUE_THREE | 

當MYDOMAIN實例被檢索的標誌地圖將有:

[ "KEY_ONE": "VALUE_ONE", "KEY_TWO": "VALUE_TWO", "KEY_THREE" :"VALUE_THREE"] 

偶爾地圖包含:

[ "KEY_ONE": "1", "KEY_TWO": "1", "KEY_THREE" :"1"]<br/> 

OR

[ "1": "VALUE_ONE", "1": "VALUE_TWO", "1" :"VALUE_THREE"] 

數據在MYDOMAIN實例中的其餘部分是正確的。這只是標誌地圖,似乎有問題。該應用程序只讀取mydomain和flags的信息,它從不更新數據。它基本上是應用程序的配置數據。

是否有其他人看到過這樣的行爲?我不知道它是否與hibernate(版本3.6.10)或Grails/Gorm或兩者有關。我一直無法在本地重現它,但它發生在兩個不同的環境中。

回答

0

我追蹤到它與休眠問題。爲永久映射生成的別名導致了鍵和元素的相同別名。這是因爲別名基於org.hibernate.mapping.Table類中的靜態計數器(在3.6.10中)。它是零星的原因是因爲Grails將所有域類加載到HashSet中,然後遍歷每個集合的綁定。由於Set是無序的,因此有時候帶有持久映射的域類將是第三類映射,導致與元素別名相同的鍵別名。

此問題已修復的Hibernate 4.1.7版本 https://hibernate.atlassian.net/browse/HHH-7545

爲了解決在Grails的問題,我劃分子類GrailsAnnotationConfiguration類,並在構造函數中,創建並丟棄10個Hibernate的表實例。在加載Grails域類之前,這會將靜態計數器遞增爲更安全的種子值。