Grails - IndexBackref的重复属性映射

时间:2016-11-28 16:18:36

标签: hibernate grails gorm

我正面临着与此博客帖子密切相关的grails(3.1.11)中的一个奇怪问题(从2010年开始!): http://codedumpblog.blogspot.de/2010/02/grails-many-to-many-with-lists.html

我试图模拟以下简单的关系:

  • 有两种父类型(OrganizationPerson)在Address关联中共享子类型(hasMany)。
  • Address只能属于父母之一,不能同时属于父母之一。
  • 删除OrganizationPerson应删除所有Address - es。

到目前为止,我有以下代码:

class Organization {
    List addresses

    static hasMany = [addresses: Address]

    static mapping = {
        addresses sort: 'country', order: 'asc', cascade: "all-delete-orphan"
    }
}

class Person {
    List addresses

    static hasMany = [addresses: Address]

    static mapping = {
        addresses sort: 'country', order: 'asc', cascade: "all-delete-orphan"
    }
}

class Address {
    String country
    //...truncated...

    static belongsTo = [organization: Organization,
                        person  : Person]

    static constraints = {
        organization nullable: true
        person nullable: true
    }
}

但是在运行之后我得到了以下Hibernate异常:

  

org.hibernate.MappingException:重复的属性映射   在com.example.Address

中找到_addressesIndexBackref

与博客文章一样,只有addresses字段在两个父类中都具有相同名称时才会出现问题。如果我将字段分别重命名为organizationAddressespersonAddresses,那么一切都按预期工作。

我希望该字段仅保留为addresses,因此我不必调用organization.organizationAddressesperson.personAddresses之类的内容。

这个近7年的问题是否有现代的解决方法?

1 个答案:

答案 0 :(得分:1)

问题

这看起来像 Hibernate Bug 。当您创建Class 通过 many-to-one

连接的两个关系时发生

在您的情况下,Address

有两个与hasMany相关的类

解决方案

membership关系替换为use关系。在你的情况下,这样做是这样的:

创建一个班级ListAddresses来保存PersonOrganization的地址:

class ListAddresses {
    List addresses

    static hasMany = [addresses: Address]

    static mapping = {
        addresses sort: 'country', order: 'asc', cascade: "all-delete-orphan"
    }
}

Address删除所有关系并创建新关系:

class Address {
    String country
    //...truncated...

    static belongsTo = [list:ListAddresses]
    /*static belongsTo = [organization: Organization,
                    person  : Person]*/

    static constraints = {
        /*organization nullable: true
        person nullable: true*/
    }
}

ListAddressesPerson

中使用Organization
class Organization {
    ListAddresses addresses

    static mapping = {
        addresses cascade: "all-delete-orphan"
    }
}

class Person {
    ListAddresses addresses

    static mapping = {
        addresses cascade: "all-delete-orphan"
    }
}

此答案基于问题。但在我的情况下,解决方案更容易,因为我替换了belongsTo关系,而不是hasMany