Спящий критерий: соединение таблицы без сопоставленной ассоциации

Я хотел бы использовать критерии hibernate api для формулировки конкретного запроса, который объединяет два объекта. Позвольте сказать, что у меня есть две сущности: Pet и Владелец с владельцем, имеющим много домашних животных, но в решающей степени эта ассоциация не отображается в аннотации Java или xml.

С hql я могу выбрать владельцев, у которых есть любимчик под названием "fido", указав соединение в запросе (вместо добавления набора домашних животных к классу владельца).

Можно ли это сделать с использованием критериев спящего режима? Если да, то как?

Спасибо, J

Ответ 1

Я понимаю, что если вы это сделаете с помощью HQL, вы создаете декартово соединение с фильтром, а не внутреннее соединение. Запросы критериев не поддерживают это.

Ответ 2

Это действительно возможно с критериями:

DetachedCriteria ownerCriteria = DetachedCriteria.forClass(Owner.class);
ownerCriteria.setProjection(Property.forName("id"));
ownerCriteria.add(Restrictions.eq("ownername", "bob"));

Criteria criteria = getSession().createCriteria(Pet.class);
criteria.add(Property.forName("ownerId").in(ownerCriteria));

Обновить. Это фактически выполняет подзапрос вместо соединения, но он позволяет использовать критерии для двух объектов, не имеющих отношения к гибернации.

Ответ 3

В NHibernate вы можете использовать подзапросы, которые определены как DetachedCriteria. Не уверен, что он работает одинаково в Java, скорее всего, это одно и то же:

DetachedCriteria pets = DetachedCriteria.For<Pet>("pet")
  .SetProjection(Projections.Property("pet.ownername"))
  .Add(/* some filters */ );

session.CreateCriteria(typeof(Owner))
  .Add(Subqueries.PropertyIn("name", pets);

Предполагается, что он соединен с именем владельца.

Ответ 4

Criterion ownerCriterion = Restrictions.sqlRestriction(SELECT ownerId FROM   Owner WHERE ownerName ='bob');
Criteria criteria = getSession().createCriteria(Pet.class);
criteria.createCriteria("ownerId").add(ownerCriterion);

Ответ 5

Там a SQLCriterion, который вы можете дать произвольным SQL, и добавьте в свой Criteria. В строке SQL токен {alias} "будет заменен псевдонимом корневого объекта."