2009-04-06 7 views
67

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

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

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

Спасибо, J

ответ

56

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

+0

Дэвид правильно на это, вы не можете сделать это с помощью критериев вы можете сделать это с HSQL –

+8

К сожалению, неожиданно получил downvote на ответ, который уже почти четыре года, без комментариев и объяснений. Кто-нибудь хочет уточнить? –

+13

Я только что дал вам случайный взлет, чтобы наверстать это. –

-1

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

+2

как это сделать? любой пример? – iPhoneJavaDev

+0

Ни один пример или (по крайней мере) ссылка не предоставлена. – n3k0

+0

SQLCriterion защитил конструктор – AndreyT

1

В 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); 

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

73

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

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)); 

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

+1

Почему так много голосов? Это все еще два разных критерия? – Reddy

+3

Работала отлично для меня, здесь идет голосование – Avanst

+30

Проблема в том, что это не объединение, а подзапрос - это значит, что вы не можете упорядочить свои результаты по столбцу из первых критериев. –

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