【问题标题】:Using Disjunction (logical or) in Grails Subqueries在 Grails 子查询中使用析取(逻辑或)
【发布时间】:2016-10-25 18:12:03
【问题描述】:

在 Grails 2.5.4 中,我在子查询中使用析取时遇到问题。如果我有如下查询:

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)
       }
   }

这回避了这个问题,实际上并不理想。知道出了什么问题吗?

更新

所以在看了更多之后,我在 Github 上找到了this issue。我遇到的是在 grails-data-mapping 版本 5.0.2 中修复的错误。因此,对于将来搜索此问题的任何人来说,您似乎要么必须升级,要么使用上面突出显示的疯狂解决方法。

【问题讨论】:

  • 你想做什么?

标签: grails grails-orm


【解决方案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])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-29
    • 2018-04-16
    • 1970-01-01
    相关资源
    最近更新 更多