Hibernate/HQL для выполнения запроса SQL WHERE ... IN (SELECT...)

Как лучше всего использовать Hibernate для получения эквивалента следующего SQL-запроса, включающего подзапрос:

SELECT cat.description, cat.code FROM
  THING_CATEGORY cat
WHERE cat.code IN (
  SELECT thing.CATEGORY_CODE FROM THING thing
  WHERE thing.COUNTRY_CODE IN ('AU', 'US', 'UK')
)

Возможно, наилучший подход - передать его непосредственно в базу данных, чтобы сделать его в исходном коде SQL (PL/SQL) моей базы данных, но на самом деле я не смог выяснить, как это делается в Hibernate. Criterion объект, поэтому я специально хочу это знать.

Пожалуйста, обратите внимание: THING таблица абсолютно массивная и имеет много столбцов, поэтому я не хочу снимать все THING сущности из базы данных для достижения этой логики, поскольку она не будет производительной. Логика для ограничения THING_CATEGORY результаты должны быть сделаны в базе данных, где они могут быть оптимизированы. На самом деле, когда я делаю запрос с необработанным PL / SQL, получение результата занимает почти целую секунду.

Чтобы дать представление о сущностях (обратите внимание, что THING_CATEGORY не имеет ссылки на THING):

@Entity @Table(name = "THING")
public class Thing
{
  private String categoryCode;
  @Column(name = "CATEGORY_CODE", nullable = false, length = 3)
  public String getCategoryCode() { return this.categoryCode; }

  private String countryCode;
  @Column(name = "COUNTRY_CODE", nullable = false, length = 2)
  public String getCountryCode() { return this.countryCode; }

  ...
}

@Entity @Table(name = "THING_CATEGORY")
public class ThingCategory
{
  private String code;
  @Id @Column(name = "CODE", unique = true, nullable = false, length = 3)
  public String getCode() { return this.code; }

  ...
}

1 ответ

Решение

Когда я собирался опубликовать вопрос, я понял, что ответ - использовать Hibernate. DetachedCriteria содержать THING подзапрос ограничения. А затем добавить это в критерии для THING_CATEGORY основной запрос.

Таким образом, код Hibernate выглядит так:

public List<ThingCategory> getRestrictedByCountrySet(List<String> countryCodes)
{
  Criterion thingCriterion = Restrictions.in("countryCode", countryCodes);
  DetachedCriteria thingSubQuery = DetachedCriteria.forClass(Thing.class)
    .add(thingCriterion)
    .setProjection(Projections.property("categoryCode");

  Criteria thingCategoryCriteria = getHbSession().createCriteria(ThingCategory.class)
    .add(Property.forName("code").in(thingSubQuery));

  return thingCategoryCriteria.list();
}
Другие вопросы по тегам