grails / gorm支持1 - 多个关联中的不同父实体

时间:2011-10-21 21:43:02

标签: grails groovy associations gorm

我有以下“顶级”(父)域实体:

客户
公司
接触

以下子实体:

地址

每个顶级域名实体之间存在一对多的关系:

客户 - >地址
公司 - >地址
联系 - >地址

即。客户,公司或联系人可以拥有一个或多个地址。

不幸的是我不知道如何用grails / gorm建模。看来我只能在地址中定义一个parent或belongsTo声明,即我无法使用以下地址声明地址:

Address {
    Customer parent //??
    Company parent //??
    Contact parent //??
}

有人可以告诉我,如果我遗失某些内容,或者是否可以以受支持的方式定义此类关系?

谢谢,

考珀

2 个答案:

答案 0 :(得分:3)

你应该可以使用belongsTo的数组版本,如Tim所指出的那样:

Address {
    static belongsTo = [Customer, Company, Contact]
}

如果实体可以共享公共地址,则可能会更改配置删除的方式。

另一种选择是拥有这三个类inherit the property from a superclass,但是在你的情况下是否有意义,我不知道(它有点看起来不像)。

答案 1 :(得分:1)

在我们的应用程序中,我们有几个需要地址的实体。但我们选择以多对多的关系对它们进行建模。

地址看起来像这样

class Address {

  // typical address properties

  Set<Company> getCompanies() {
    CompanyAddress.findAllByAddress(this).collect { it.company } as Set
  }

  static constraints = {
    // typical constraints
  }
}

对于每个&#34;父母&#34;我们提供一个吸气剂。您可以在上面的代码中看到getCompanies()。如果您每个地址只有一个公司,那么只需让该公司返回1公司而不是Set。在公司内部反之亦然,我们有一个getAddresses()。

例如,

公司地址看起来像这样......

class CompanyAddress implements Serializable{

  Address address
  Company company

  boolean equals(other) {

    if (this.is(other)){
      return true
    }

    if (!(other instanceof CompanyAddress)) {
      return false
    }

    other.address?.id == address?.id &&
        other.company?.id == company?.id
  }

  int hashCode() {
    def builder = new HashCodeBuilder()
    if (address) builder.append(address.id)
    if (company) builder.append(company.id)
    builder.toHashCode()
  }

  static CompanyAddress get(long companyId, long addressId) {
    find 'from CompanyAddress where address.id=:addressId and company.id=:companyId',
      [addressId: addressId, companyId: companyId]
  }

  static CompanyAddress create(Company company, Address address, boolean flush = false) {
    new CompanyAddress(address: address, company: company).save(flush: flush, insert: true)
  }

  static boolean remove(Company company, Address address, boolean flush = false) {
    CompanyAddress instance = CompanyAddress.findByAddressAndCompany(address, company)
    instance ? instance.delete(flush: flush) : false
  }

  static void removeAll(Address address) {
    executeUpdate 'DELETE FROM CompanyAddress WHERE address=:address', [address: address]
  }

  static void removeAll(Company company) {
    executeUpdate 'DELETE FROM CompanyAddress WHERE company=:company', [company: company]
  }

  static mapping = {
    id composite: ['address', 'company']
    version false
  }
}