2009-04-06 6 views
67

Je voudrais utiliser les critères d'Hibernate api pour formuler une requête particulière qui relie deux entités. Disons que j'ai deux entités, Pet et Owner avec un propriétaire ayant beaucoup d'animaux de compagnie, mais crucialement cette association n'est pas mappée dans les annotations Java ou xml. Avec hql, je pouvais sélectionner les propriétaires qui ont un animal de compagnie appelé 'fido' en spécifiant la jointure dans la requête (plutôt que d'ajouter un ensemble d'animaux de compagnie à la classe propriétaire).Critères d'Hibernation: Joindre une table sans une association mappée

Peut-on faire de même avec les critères d'hibernation? Si c'est le cas, comment?

Merci, J

Répondre

56

je crois comprendre que si vous faites cela en utilisant HQL, vous créez une jointure cartésienne avec un filtre, plutôt que d'une jointure interne. Les requêtes de critères ne supportent pas cela.

+0

David est correct sur ce point, vous ne pouvez pas faire cela avec un critères que vous pouvez le faire avec HSQL –

+8

Désolé, eu tout à coup un downvote sur une réponse qui est près de quatre ans, sans commentaire ni explication. Quelqu'un veut-il élaborer? –

+13

Je viens de vous donner un upvote aléatoire pour compenser –

-1

Il ya un SQLCriterion, que vous pouvez donner arbitrairement SQL, et l'ajouter à votre Criteria. Dans la chaîne SQL, le jeton {alias} "sera remplacé par l'alias de l'entité racine."

+2

comment faire ceci? un exemple? – iPhoneJavaDev

+0

Aucun exemple ou (au moins) lien fourni. – n3k0

+0

SQLCriterion a protégé le constructeur – AndreyT

1

Dans NHibernate, vous pouvez utiliser des sous-requêtes qui sont définies comme DetachedCriteria. Je ne sais pas si cela fonctionne même en Java, plus probablement est le même:

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

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

est supposé qu'il rejoint en utilisant le nom du propriétaire.

73

C'est en effet possible avec les critères:

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

Mise à jour: exécute en fait une sous-requête au lieu d'une jointure, mais il vous permet d'utiliser des critères sur deux entités qui ne disposent pas d'une relation de mise en veille prolongée défini.

+1

pourquoi il y a tant de mises à jour? Il reste deux critères différents non? – Reddy

+3

Fonctionne parfaitement pour moi, voici un vote à venir – Avanst

+30

Problème est ce n'est pas une jointure, mais sous-requête - ce qui signifie que vous ne pouvez pas ordonner vos résultats par une colonne de premier critère. –

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