Критерии гибернации ограничены агрегацией - PullRequest
4 голосов
/ 18 марта 2011

Фон

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

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

Из-за ограничений системы, с которой мы работаем, мы должны использовать Hibernate Criteria API, а не HQL. Набор данных потенциально очень большой.

Проблема

Я предложил следующий подход:

Получите последний результат прохождения для каждого тестового элемента, затем объедините его с таблицей testResults, чтобы получить идентификаторы TestResults, которые не выполняются с момента последнего прохода

SELECT 
  test.id, 
  item.id, 
  COUNT(item.id) 
FROM testResults 
INNER JOIN (SELECT item.id, test.id, MAX(testDate) FROM testResults GROUP BY item.id, test.id) AS lastPass
ON (lastPass.item.id = item.id AND lastPass.test.id = test.id)
GROUP BY
  test.id
  item.id

Как я могу создать это внутреннее объединение, используя Criteria API? Подзапросы работают только в разделе WHERE, поэтому они не подходят.

Следующий код создает критерий, который получает дату последнего теста для каждой комбинации тест / элемент, но мне нужен TestResult, которому принадлежит эта дата.

DetachedCriteria maxDate = new DetachedCriteria(TestResult.class, "maxDate");
maxDate.setProjection(Projections.projectionList()
    .add(Projections.max("testDate"))
    .add(Projections.groupProperty("test"))
    .add(Projections.groupProperty("item"))
    );
maxDate.add(Property.forName("maxDate.test").eqProperty("mainQuery.test"));
maxDate.add(Property.forName("maxDate.item").eqProperty("mainQuery.item"));

Любая помощь будет высоко ценится,

1 Ответ

3 голосов
/ 22 марта 2011

Я думаю, вы достаточно близки, вам не нужно указывать Property.forName для ссылки на основной запрос из подзапроса:

    Criteria mainQuery = getSession().createCriteria(TestResult.class, "mainQuery");

    DetachedCriteria maxDate = new DetachedCriteria(TestResult.class, "maxDate");
    maxDate.setProjection(Projections.projectionList()
            .add(Projections.max("testDate"))
            .add(Projections.groupProperty("test"))
            .add(Projections.groupProperty("item")));
    maxDate.add(Restrictions.eqProperty("maxDate.test", "mainQuery.test"));
    maxDate.add(Restrictions.eqProperty("maxDate.item", "mainQuery.item"));

    mainQuery.setProjection(Projections.projectionList()
            .add(Projections.groupProperty("test"))
            .add(Projections.groupProperty("item"))
            .add(Projections.rowCount()));

    result = mainQuery.list();

    //use some AliasToBeanResultTransformer to convert the projected result into beans

Попробуйте, если это работает ...

...