2011-01-12 7 views
1

私は2つのドメインクラスを持っています。 1つは「パートナー」で、もう1つは「顧客」です。顧客は、パートナーの一部にすることができますし、パートナーが1件の以上のお客様持つことができます。私は、顧客は、このように、パートナーの一部であるかどうかを確認しようとするたびに、しかしjoinTableを使用したGrailsの1対多マッピング

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'] 
    } 
} 

を:

私は次のエラーを取得する:見つけることが想定されている、それはPartnerMapテーブルにある...

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を考えているかのように見えますがお客様のクエリの一部であり、そうではありませんcustomer_id、t鶏は、対応するpartner_idからパートナーを取得します。

誰かが私が間違っていることを何か手がかりがありますか?

編集:私はレガシーデータベーステーブルでこれをやっていることを言いました。だから私はパートナー、顧客、PartnerMapテーブルを持っています。 PartnerMapには、customer_idフィールドとpartner_idフィールドがあります。

答えて

5

ジョインテーブルを使用するときに1-manyが動作すると仮定すると、標準GORMでは双方向にしてカスタマーのパートナーにアクセスすることはできません。あなた以来

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' 
    } 
} 

お客様:

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

パートナー:

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

PartnerMapしかし、あなたは、ドメインクラスとアクセスもので、そのようにテーブルに参加マッピングすることができますhasManyを使用していない場合、addToXXX動的メソッドは失われますが、PartnerMap.create()を呼び出して2つを関連付けることができますインスタンス。あなたはまた、ドメインクラスでコレクションとバックリファレンスを失いますが、それらのユーティリティメソッドを追加しました。

+0

おっと、忘れてしまいましたが、私はこれまでのデータベースのことでこれをやっています...だから、あらかじめ定義されたテーブルで作業する必要があります。 Customer、Partner、およびPartnerMapテーブルがあります。 PartnerMapは単にcustomer_idフィールドとpartner_idフィールドです。これは私を制限しますか? – intargc

+0

私はこの問題がGrailsコンソールの内部にロードしようとしているときにのみ存在することを認識しました。なぜか...私はGrailsのコンソールがRailsのような環境に適切にロードされていると仮定しました... – intargc

+0

私はコードを修正しましたが、コンソールの外で動作していればより簡単な解決方法を使用する必要があります。コンソールはGrailsのランタイム環境に非常に近いですが、ランアプリケーションや戦争中に展開されたときには多くのことが起こっており、コンソールはその環境に近似しています。 –

関連する問題