2011-01-12 101 views
1

我有兩個領域類。一個是「合作伙伴」,另一個是「客戶」。客戶可以成爲合作伙伴的一部分,合作伙伴可以有1個或多個客戶:Grails與joinTable的一對多映射

class Customer { 
    Integer id 
    String name 
    static hasOne = [partner:Partner] 
    static mapping = { 
     partner joinTable:[name:'PartnerMap',column:'partner_id',key:'customer_id'] 
    } 
} 

class Partner { 
    Integer id 
    static hasMany = [customers:Customer] 
    static mapping = { 
     customers joinTable:[name:'PartnerMap',column:'customer_id',key:'partner_id'] 
    } 
} 

但是,每當我嘗試看看如果客戶是合作伙伴的一部分,就像這樣:

我得到以下錯誤:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; SQL [select this_.customer_id as customer1_162_0_, this_.company as company162_0_, this_.display_name as display3_162_0_, this_.parent_customer_id as parent4_162_0_, this_.partner_id as partner5_162_0_, this_.server_id as server6_162_0_, this_.status as status162_0_, this_.vertical_market as vertical8_162_0_ from Customer this_]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query 

看起來好像Grails是想PARTNER_ID是客戶查詢的一部分,它不...它是在PartnerMap表,這是應該找customer_id,t母雞從相應的partner_id獲取合作伙伴。

任何人有任何線索我做錯了什麼?

編輯:我忘了提及我正在做這與遺留數據庫表。所以我有一個合作伙伴,客戶和PartnerMap表。 PartnerMap只有一個customer_id和partner_id字段。

回答

5

鑑於您想要連接表的方式有很多,我認爲標準GORM無法使其成爲雙向訪問客戶的合作伙伴。但是,您可以映射連接表與域類和訪問的東西,道:

客戶:

class Customer { 
    String name 
    def getPartner() { 
     PartnerMap.findByCustomer(this)?.partner 
    } 
} 

合作伙伴:

class Partner { 
    String name 
    def getCustomers() { 
     PartnerMap.findAllByPartner(this)*.customer 
    } 
} 

PartnerMap:

import org.apache.commons.lang.builder.HashCodeBuilder 

class PartnerMap implements Serializable { 

    Partner partner 
    Customer customer 

    boolean equals(other) { 
     if (!(other instanceof PartnerMap)) { 
     return false 
     } 

     other.partner?.id == partner?.id && 
     other.customer?.id == customer?.id 
    } 

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

    static PartnerMap get(long partnerId, long customerId) { 
     find 'from PartnerMap where partner.id=:partnerId and customer.id=:customerId', 
     [partnerId: partnerId, customerId: customerId] 
    } 

    static PartnerMap create(Partner partner, Customer customer, boolean flush = false) { 
     new PartnerMap(partner: partner, customer: customer).save(flush: flush, insert: true) 
    } 

    static boolean remove(Partner partner, Customer customer, boolean flush = false) { 
     PartnerMap instance = PartnerMap.findByPartnerAndCustomer(partner, customer) 
     instance ? instance.delete(flush: flush) : false 
    } 

    static void removeAll(Partner partner) { 
     executeUpdate 'DELETE FROM PartnerMap WHERE partner=:partner', [partner: partner] 
    } 

    static void removeAll(Customer customer) { 
     executeUpdate 'DELETE FROM PartnerMap WHERE customer=:customer', [customer: customer] 
    } 

    static mapping = { 
     id composite: ['customer', 'partner'] 
     version false 
     table 'PartnerMap' 
    } 
} 

既然你'不使用hasMany,你失去了addToXXX動態方法,但你可以撥打PartnerMap.create()來關聯兩個實例。你也失去了域類中的集合和反引用,但我爲這些添加了實用方法。

+0

糟糕,我忘了提及,我正在做這與傳統的數據庫的東西...所以我必須使用預定義的表。我有一個客戶,合作伙伴和PartnerMap表。 PartnerMap只是一個customer_id和partner_id字段。這是否限制了我? – intargc 2011-01-12 23:20:31