Размер ассоциации в критериях гибернации - PullRequest
1 голос
/ 16 мая 2010

Я столкнулся с проблемой при обращении с критериями Hibernate в Grails.

Взгляните:

def visitors = Client.withCriteria{
          visits{
             use ( TimeCategory ) {between('date',date,date+1.month-1)}
          }
          sizeGe("visits",params.from)
          sizeLe("visits",params.to)
          fetchMode("visits", FM.JOIN)
};

Мне нужны только те клиенты, у которых количество посещений в месяц между от и до границ.

Но теперь размер * ограничения применяются ко всем посещениям. Так что, если у клиента есть одно посещение в этом месяце и посещение в предыдущем месяце. И если я установлю из = 2 , этот клиент будет в результате. Но его там быть не должно.

// UPD: дело в том, что ограничения sizeGe и sizeLe работают не так, как я ожидаю.

С моей точки зрения, они должны применяться после между ограничением, но это не так.

Например:

def client = new Client();

client.visits.add(new Visit(date:'2010-03-16'));
client.visits.add(new Visit(date:'2010-05-16'));
client.visits.add(new Visit(date:'2010-05-17'));
client.save();

И тогда я хочу, если:

  • date = Date.parse ('гггг-ММ', '2010-05')
  • params.from = 2

критерии должны вернуть этого клиента, а если

  • params.from = 3

не возвращается;
Но это возвращается, потому что sizeGe применяется к всем посещениям, независимо от того, какая дата у них есть.

// END UPD.

Дайте мне знать, если что-то еще не ясно.

Любая помощь приветствуется.

Спасибо, Вова.

Ответы [ 2 ]

1 голос
/ 17 мая 2010

Для этого вам понадобится пункт имения, и я обнаружил, что проблема открыта в Jira Hibernate, чтобы добавить поддержку для этого.

Между тем вы должны использовать HQL и написать запрос вручную, см. . Если вам не нужно изменять ограничения запроса, основанные на некоторых выбранных полях, вы должны всегда использовать HQL, он может быть кэширован.

0 голосов
/ 18 мая 2010

Спасибо, Фелипе.

Кроме того, я решил использовать sqlRestriction. Конечно, у него есть проблемы с переносимостью, но он работает:

def visitors = c.listDistinct{
        use(TimeCategory){
                visits{

                    between('date',date,date+1.month-1)
                }

                sqlRestriction(
                        """(
                            select count(*)
                                  from visit v
                            where
                                v.visitor_id={alias}.id
                                and v.date between 
                                      '${date.format("yyyy-MM-dd")}' 
                                      and '${(date+1.month-1).format("yyyy-MM-dd")}'
                            )
                            between ${params.from} and ${params.to}"""
                )
            }
    }

Спасибо, Вова.

...