Запрос критериев Grails повторяет повторяющиеся экземпляры - PullRequest
5 голосов
/ 19 октября 2011

У меня есть класс домена с именем Order, и этот класс имеет отношение hasMany с классом Item. Когда я запрашиваю список заказов с определенными ограничениями, я получаю столько раз Order, сколько items.

Так, например, Order экземпляр имеет, скажем, ссылки на 3 экземпляра Item, тогда вызов критерия для Order возвращает 3 дубликата Order. Я не уверен, но стоит ли упоминать, что для класса домена Order fetchMode имеет значение "eager".

Я действительно озадачен тем, что там происходит. Любая помощь в этом отношении будет принята с благодарностью. Фрагмент кода прилагается:

def clazz = "cust.Order"
def criteria = clazz.createCriteria()
        println("clazz == "+Order.list())// returning correct data i.e unique instance of order
        def filter = {
                    // trimmed down all filtering criteria for debugging
            }//close filter
        List results = criteria.list(max:params?.max,offset:params?.offset,filter)
            results.each{Object data->
                println(data.getClass())
            }
        println("results == "+results)

Еще раз спасибо

Ответы [ 4 ]

4 голосов
/ 19 октября 2011

Если вы позвоните criteria.listDistinct вместо criteria.list, дубликаты будут удалены

3 голосов
/ 05 июля 2013

Одним из решений является использование этого в вашем запросе:

resultTransformer org.hibernate.Criteria.DISTINCT_ROOT_ENTITY
2 голосов
/ 19 октября 2011

Criteria API - это просто оболочка для построения SQL-запроса.В вашем случае в рассматриваемом запросе содержатся JOINs (из-за стремительной выборки), и он возвращает декартово произведение ордеров и соответствующих им предметов.Каждая возвращаемая строка включается в результаты как отдельный экземпляр Order.

Самый простой способ удалить дубликаты - поместить все результаты в Set, например:

def resultSet = new HashSet()
resultSet.addAll(results)
println("results == " + resultSet)
0 голосов
/ 19 октября 2011

Вы также можете использовать динамические искатели, как в Order.findAllBy *. В зависимости от сложности вашего фильтра, это может быть легко или сложно :)

...