2011-10-21 166 views
1

我有以下的「頂級」(父)域實體:Grails的/格姆在1支持不同的母公司 - 許多聯想

客戶
公司
聯繫

而下面的孩子實體:

地址

有一對多的關係每個噸之間OP級域實體:

客戶 - >地址
公司 - >地址
聯繫 - >地址

即一個客戶,公司或聯繫人可以有一個或多個地址。

不幸的是我不知道如何在grails/gorm中建模。看來我只能定義在地址父母一方或屬於關聯聲明,即我不能使用申報地址:

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

誰能告訴我,如果我失去了一些東西,或者如果它有可能在定義這種關係支持的方式?

感謝,

考珀

+0

也許相關:http://stackoverflow.com/questions/5533305/grails-belongsto-cascade-on-delete-when-belongsto -specified-multiple-classes –

回答

3

您應該能夠使用的belongsTo數組版本蒂姆指出:

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

如果實體可以共享一個公共地址可能會改變你的方式配置刪除。

另一個選擇是讓這三個類別inherit the property from a superclass,但是否在您的的情況下有意義,我不知道(它看起來不像它)。

+1

我通常更喜歡地圖方法static belongsTo = [customer:Customer,company:Company,contact:Contact] – Gregg

+0

@Gregg是的,我也是。 –

+0

謝謝你。當我嘗試這種方式時,我遇到了非法backRef關聯的問題,但搜索該問題表明我需要解決另一個問題,這應該起作用。 ta' –

1

在我們的應用程序中,我們有幾個需要地址的實體。但我們選擇以多對多的關係對它們進行建模。

地址看起來像這樣

class Address { 

    // typical address properties 

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

    static constraints = { 
    // typical constraints 
    } 
} 

併爲每個 「父」 我們提供一個getter。你可以在上面的代碼中看到getCompanies()。如果你只是每個地址都有一家公司,那麼只需讓該getter返回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 
    } 
} 
+0

感謝Gregg,我喜歡這個解決方案,並可能在將來使用它。我假設用這種方式建模它失去了在關係中使用條件查詢的能力?你遇到的其他缺點? –

+0

不,我不知道。它解決了很多性能問題(至少在Grails 2.0包的實現之前)。 http://www.infoq.com/presentations/GORM-Performance – Gregg