Hibernate PersistentMap返回错误的值

时间:2015-11-05 01:04:16

标签: java hibernate grails gorm

我正在开发一个运行Grails 2.4.5和Hibernate 3.6.10的应用程序。 有一个域对象具有子PersistentMap。这张地图存储4 键值对,其中值始终为String。

在我们的开发和测试环境中,一切正常,然后偶尔 持久性地图开始返回" 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和Owner):

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或两者相关。我已无法在本地重现它,但它发生在两个不同的环境中。

1 个答案:

答案 0 :(得分:0)

我将其追溯到hibernate的问题。为持久映射生成的别名导致密钥和元素具有相同的别名。这是因为别名基于org.hibernate.mapping.Table类中的静态计数器(在3.6.10中)。它是零星的原因是因为Grails将所有域类加载到HashSet中,然后迭代每个域绑定。由于Set是无序的,因此具有持久映射的域类将是映射的第3类,从而产生与元素别名相同的键别名。

此问题已在Hibernate 4.1.7版中修复 https://hibernate.atlassian.net/browse/HHH-7545

为了解决Grails中的问题,我将GrailsAnnotationConfiguration类子类化,并在构造函数中创建并丢弃了10个Hibernate Table实例。在加载Grails域类之前,这会将静态计数器增加到更安全的种子值。