2016-10-25 49 views
1

在Grails 2.5.4中,我遇到了在子查詢中使用分離的問題。如果我有如下查詢:在Grails子查詢中使用分離(邏輯或)

DomainObj.createCriteria().list { 
    def criteria = new DetachedCriteria(DomainObj2).build { 
     or { 
      eq('prop1', someVal) 
      eq('prop2', someVal) 
      eq('prop3', someVal) 
     } 
     projections { 
      distinct('id') 
     } 
    } 
    inList('prop', criteria) 
} 

查詢的'或'部分失敗,出現空指針異常。原因似乎是在AbstractHibernateCriterionAdapter中,代碼正在爲未分配的DetachedCriteria尋找PersistentEntity。

我發現的唯一的解決方法是切換查詢中使用子查詢更多像這樣的:

def criteria1 = new DetachedCriteria(DomainObj2).build { 
      eq('prop1', someVal) 
     projections { 
      distinct('id') 
     } 
    } 
    def criteria2 = new DetachedCriteria(DomainObj2).build { 
      eq('prop2', someVal) 
     projections { 
      distinct('id') 
     } 
    } 
    def criteria3 = new DetachedCriteria(DomainObj2).build { 
      eq('prop3', someVal) 
     projections { 
      distinct('id') 
     } 
    } 
    DomainObj.createCriteria().list { 
     or { 
      inList('prop', criteria1) 
      inList('prop', criteria2) 
      inList('prop', criteria3) 
     } 
    } 

這回避了問題,真的是不理想的。任何想法出了什麼問題?

更新

於是四處尋找一些我發現this issue Github上後。我遇到的是在grails-data-mapping版本5.0.2中修復的錯誤。因此,對於任何未來搜索此問題的人來說,您似乎都必須升級或使用上面強調的瘋狂解決方法。

+0

你想做什麼? – injecteer

回答

1

你也許可以簡化以上工作巢:

private DetachedCriteria getCriteria(prop,val) { 
     return new DetachedCriteria(DomainObj2).build { 
      eq(prop,val) 
     projections { 
      distinct('id') 
     } 
    } 
    DomainObj.createCriteria().list { 
     or { 
      inList('prop', getCriteria('prop1','somVal')) 
      inList('prop', getCriteria('prop2','somVal')) 
      inList('prop', getCriteria('prop3','somVal')) 
     } 
    } 

個人而言,我很可能要麼只是do a findAll或只是運行HQL查詢,如果事實證明你不能用當前的方法由於一些因爲我不是這方面的專家。

//where d.domainObject2 is the binding of DomainObj2 within DomainObj 
    String query="select new map(d.id) from DomainObj d left join d.domainObject2 d2 where d2.field in (:someList)" 
def input=[] 
input.someList=[1,2,3] //The or segments 
    def results=DomainObj.executeQuery(query,[],[readOnly:true,timeout:15,max:-1])