2016-10-25 1 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 код ищет PersistentEntity для DetachedCriteria, который никогда не назначается.

Единственный способ решения проблемы я нашел, чтобы переключить запрос использовать больше подзапросы, как это:

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

Что обходит проблему, и на самом деле не является идеальным. Любая идея, что происходит не так?

Update

Так осмотрев еще немного я нашел 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]) 
Смежные вопросы