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 回答