Grails 2.5.1 (hibernate 3) criteria multiple joins

2019-03-05 12:28发布

问题:

I've found similar questions, but no answers.

class SomeDomain {
    static hasMany= [productData:ProductData]
}

ProductData is simple type/value pair

I'm trying to find all SomeDomains that have multiple products of certain type (in a loop). Currently the relevant portion of the criteria looks like:

SomeDomain.createCriteria.list {
  somedata.each { type, value ->
    productData {
      eq("type", type)
      eq("value", value)
    }
  }
}

However, this generates only a single join with the SQL:

from some_domain this_ inner join product_data productdata_a1_ on this_.id=productdata_a1_.some_domain_id 
where (productdata_a1_.type_id=4 and productdata_a1_.value='GC') 
and (productdata_a1_.type_id=5 and productdata_a1_.value='P1') 

obviously type_id is never going to succeed on and'd checks for =4 and =5...

What I'd really like is two inner joins to product_data... can't figure out how to force this, though.

I tried createAlias("productData", "product-${index}") this gave org.hibernate.QueryException: duplicate association path: productData

回答1:

Unsure why you need multiple joins to same table ? if question is understood correctly

String query="from someDomain sd join productData pd where pd.type in (:types) and pd.value in (:values) "
def inputParams=[:]
inputParams.values=['GC','P1']
inputParams.types=[4,5]
List resultsList = SomeDomain.executeQuery(query,inputParams,[readOnly:true,timeout:15])

pd.type may have to be another join since in the debug it attempts to get the .id so add another join

  String query="from someDomain sd join productData pd join pd.types tp where tp.id in (:types) and pd.value in (:values) "

If you wanted to do multiple joins as suggested in the question

  String query="from someDomain sd join productData pd join pd.types tp, ProductData pd2 where tp.id in (:types) and pd.value in (:values) and pd2.something=pd.something"

That is then going off and looking productData that is linked to someDomain then again looking up entire ProductData as pd2 and then confirming where pd2.something = pd.something

Using comma's in HQL becomes a new lookup not related to existing query..