我有以下1 - M(单向)关系:
Customer (1) -> (M) Address
我正在尝试过滤包含特定文本的特定客户的地址,例如
def results = Customer.withCriteria {
eq "id", 995L
addresses {
ilike 'description', '%text%'
}
}
问题是这会返回客户,当我依次访问“地址”时,它会提供完整的地址列表,而不是过滤的地址列表。
由于无法从条件查询中访问关联表,因此我无法使用Address.withCriteria
。
我希望避免恢复原始SQL查询,因为这意味着无法使用大量功能来灵活且可重用地构建条件查询。
很想听到任何想法......
答案 0 :(得分:1)
我相信2.1中不同行为的原因是here
具体来说:
以前默认的LEFT JOIN用于跨关联的条件查询现在是INNER JOIN。
IIRC,当您使用内部联接时,Hibernate不会急切地加载关联。
您似乎可以使用createAlias
指定外部联接example here:
我对这个特殊问题的体验来自于NHibernate的经验,所以我无法真正了解如何使它正常工作。如果结果不正确,我很乐意删除这个答案。
答案 1 :(得分: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