J'aimerais utiliser l'API des critères d'Hibernate pour formuler une requête particulière qui joint deux entités. Supposons que j'ai deux entités, Pet et Owner, avec un propriétaire possédant de nombreux animaux de compagnie, mais surtout, cette association n'est pas mappée dans les annotations Java ou XML.
Avec hql, je pouvais sélectionner les propriétaires ayant 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 de propriétaire).
Peut-on faire la même chose en utilisant des critères d'hibernation? Si c'est le cas, comment?
Merci, J
D'après ce que je comprends, si vous utilisez HQL pour cela, vous créez une jointure cartésienne avec un filtre plutôt qu'une jointure interne. Les requêtes de critères ne prennent pas en charge cette opération.
Ceci 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));
Update : Ceci effectue en fait une sous-requête au lieu d'une jointure, mais vous permet d'utiliser des critères sur deux entités pour lesquelles aucune relation de veille prolongée n'est définie.
Dans NHibernate, vous pouvez utiliser des sous-requêtes définies en tant que DetachedCriteria. Je ne sais pas si cela fonctionne de la même manière en Java, très probablement, c'est pareil:
DetachedCriteria pets = DetachedCriteria.For<Pet>("pet")
.SetProjection(Projections.Property("pet.ownername"))
.Add(/* some filters */ );
session.CreateCriteria(typeof(Owner))
.Add(Subqueries.PropertyIn("name", pets);
Supposé qu'il est rejoint en utilisant le nom du propriétaire.
Criterion ownerCriterion = Restrictions.sqlRestriction(SELECT ownerId FROM Owner WHERE ownerName ='bob');
Criteria criteria = getSession().createCriteria(Pet.class);
criteria.createCriteria("ownerId").add(ownerCriterion);