2

次の 1 - M (一方向) の関係があります。

Customer (1) -> (M) Address

特定のテキストを含む特定の顧客の住所をフィルタリングしようとしています。

def results = Customer.withCriteria {
    eq "id", 995L
    addresses {
        ilike 'description', '%text%'
    }
}

問題は、これが顧客を返し、「アドレス」にアクセスすると、フィルタリングされたアドレスのリストではなく、アドレスの完全なリストが返されることです。

Address.withCriteria条件クエリから関連付けテーブルにアクセスできないため、使用できません。

柔軟で再利用可能な方法で基準クエリを構築するために用意されている多くの機能を使用できなくなるため、未加工の SQL クエリに戻すことは避けたいと考えています。

どんな考えも聞きたいです...

4

2 に答える 2

1

2.1 での動作の違いの理由はここに文書化されていると思います

具体的には次の点です。

アソシエーションにまたがる条件クエリの LEFT JOIN の以前のデフォルトは、INNER JOIN になりました。

IIRC、Hibernate は、内部結合を使用するときにアソシエーションを積極的にロードしません。

createAliasここで外部結合のを指定するために使用できるようです:

この特定の問題に関する私の経験は、NHibernate の経験からのものであるため、正しく動作させることについてこれ以上光を当てることはできません。この回答が間違っていることが判明した場合は、喜んで削除します。

于 2012-08-25T04:39:56.237 に答える
0

これを試して:

def results = Customer.createCriteria().listDistinct() {
    eq('id', 995L)
    addresses {
        ilike('description', '%Z%')
    }
}

これにより、正しい ID と一致する住所を持ち、一致する住所のみを持つ Customer オブジェクトが得られます。

このクエリ (少し変更) を使用して、住所が一致するすべての顧客を取得することもできます。

def results = Customer.createCriteria().listDistinct() {
    addresses {
        ilike('description', '%Z%')
    }
}

results.each {c->
    println "Customer " + c.name
    c.addresses.each {address->
        println "Address " + address.description
    }
}

編集 ドメインクラスとアドレスを追加した方法は次のとおりです。

class Customer {
  String name
  static hasMany = [addresses: PostalAddress]
  static constraints = {
  }
}
class PostalAddress {
  String description
  static belongsTo = [customer: Customer]
  static constraints = {
  }
}
//added via Bootstrap for testing
def init = { servletContext ->
    def custA = new Customer(name: 'A').save(failOnError: true)
    def custB = new Customer(name: 'B').save(failOnError: true)
    def custC = new Customer(name: 'C').save(failOnError: true)

    def add1 = new PostalAddress(description: 'Z1', customer: custA).save(failOnError: true)
    def add2 = new PostalAddress(description: 'Z2', customer: custA).save(failOnError: true)
    def add3 = new PostalAddress(description: 'Z3', customer: custA).save(failOnError: true)
    def add4 = new PostalAddress(description: 'W4', customer: custA).save(failOnError: true)
    def add5 = new PostalAddress(description: 'W5', customer: custA).save(failOnError: true)
    def add6 = new PostalAddress(description: 'W6', customer: custA).save(failOnError: true)

}

これを実行すると、次の出力が得られます。

Customer A
Address Z3
Address Z1
Address Z2
于 2012-08-21T16:19:08.437 に答える