Запрос критериев гибернации для нескольких столбцов с предложением IN и подвыборкой

У меня вопрос, очень похожий на этот вопрос.

Я выбираю все данные из table1 для всех совпадающих уникальных комбинаций field3 и field4 из table2.

Вот мой урезанный SQL:

select *
from table1 as t1
where (t1.field1, t1.field2) in (select distinct field3, field4
                                 from table2 as t2
                                 where t2.id=12345);

Мне нужно перевести мой SQL в критерии гибернации. У меня есть объекты моей сущности, правильно отображаемые в таблицы, и я преобразую ответ в правильную сущность результата, но я не могу правильно перевести свое предложение where.

Что у меня есть

Criteria criteria = getSession().createCriteria(Table1.class);

DetachedCriteria subquery = DetachedCriteria.forClass(Table2.class);
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("field3"), "field3");
projectionList.add(Projections.property("field4"), "field4");
subquery.setProjection(Projections.distinct(projectionList));
subquery.add(Restrictions.eq("id", 12345));

Я хочу, чтобы мое предложение where было примерно таким:

criteria.add(Subqueries.in("field1, field2", subquery));

Но это не разрешено Hibernate.

Я попытался развернуть предложение where, чтобы иметь два подзапроса и проверять результаты field1 и field2, но похоже, что подзапросы всегда должны возвращать несколько столбцов. Я сделал это с помощью group by, но Hibernate автоматически добавит столбцы в group by в список проекций, и я не могу найти способ их удалить.

Вот тот же запрос с использованием group by:

select *
from table1 as t1
where t1.field1 in (select field3
                    from table2 as t2
                    where t2.id=12345
                    group by field3, field4)
  and t1.field2 in (select field4
                    from table2 as t2
                    where t2.id=12345
                    group by field3, field4);

Можно ли сделать мое предложение where с использованием критериев гибернации?

Если невозможно использовать критерии гибернации, можно ли выполнить мое предложение where с помощью HQL?

РЕДАКТИРОВАТЬ:

@ Larry.Z отвечает на мой вопрос, используя HQL.

Мне удалось решить свою проблему с помощью критериев гибернации, но мне пришлось изменить запрос, чтобы:

select *
from table1 as t1
where exists (select 1
              table2 as t2
              where t2.id=12345
                and t2.field3=t1.field1
                and t2.field4=t1.field2);

Переведено в критерии гибернации:

Criteria criteria = getSession().createCriteria(Table1.class, "t1");

DetachedCriteria subquery = DetachedCriteria.forClass(Table2.class, "t2");
subquery.add(Restrictions.eq("t2.id", 12345));
subquery.add(Restrictions.eqProperty("t2.field3", "t1.field1"));
subquery.add(Restrictions.eqProperty("t2.field4", "t1.field2"));
subquery.setProjection(Projections.property("t2.id")); // select the ID rather than 1

Мне все еще любопытно, можно ли написать критерии гибернации с использованием моего исходного SQL.


person CoffeePasta    schedule 04.11.2013    source источник
comment
Ограничения имеют И, ИЛИ и т. Д., Это то, что вы ищете? docs.jboss.org/hibernate/core/3.3/api/org/hibernate/criterion/   -  person kosa    schedule 05.11.2013
comment
Нет, не думаю. Я пытаюсь написать предложение IN, используя кортежи в критериях гибернации. Не похоже, что спящий режим позволит мне вернуть кортеж (например, ['field3', 'field4']) из дополнительного выбора; и не позволит мне сравнивать кортежи с помощью IN. В качестве альтернативы я попытался развернуть свой запрос, добавив два подзапроса, но Hibernate любит добавлять дополнительные столбцы в проекцию. Посмотрите на мой первый подзапрос - группировка по field3 и field4 вернет и field3, и field4 в результатах подзапроса, хотя я указываю только для возврата field3.   -  person CoffeePasta    schedule 05.11.2013


Ответы (2)


Попробуйте написать HQL-запрос вот так

String hql = "from Table1 t1 where (t1.field1, t1.field2) in (
    select distinct t2.field3, t2.field4
    from Table2 t2
    where t2.id=12345)";
sessionFactory.getCurrentSession().createQuery(hql).list()
person Larry.Z    schedule 05.11.2013
comment
Спасибо, Larry.Z. По какой-то причине я не мог заставить работать '(tuple) in (sub select)' раньше. Я бы предпочел придерживаться критериев гибернации, если это возможно, но это отличная альтернатива! - person CoffeePasta; 05.11.2013

Subqueries.propertiesIn - это то, что вам нужно:

criteria.add(Subqueries.propertiesIn(
                new String[] { "field1", "field2" },
                detachedCriteria));
person iTake    schedule 27.08.2014