Hibernate Criteria join query un à plusieurs
J'ai une classe de chat et une classe de propriétaire. Un chat a un propriétaire, mais un propriétaire peut avoir beaucoup de chats. Ce que je veux requête est obtenir tous les propriétaires qui ont un chat aux yeux bleus.
class Cat {
Owner owner; //referenced from Owner.id
String eyeColor;
}
class Owner {
List<Cat> catList;
}
J'ai essayé quelques codes mais je ne sais vraiment pas quoi faire.
Criteria criteria = getCurrentSession().createCriteria(cat.getClass(), "cat");
criteria.createAlias("cat.owner", "owner");
criteria.add(Restrictions.eq("cat.eyeColor", "blue");
2 réponses
Les critères
Ne peuvent sélectionner que des projections ou l'entité racine. Ce n'est pas quelques a rejoint l'entité. Certaines requêtes sont donc impossibles à exprimer avec des critères (ce qui est une bonne raison de plus d'utiliser HQL, en plus d'une bien meilleure lisibilité et concision).
Tout n'est pas perdu, cependant, parce que votre association est bidirectionnelle. Donc, vous avez juste besoin de l'équivalent de la requête HQL
select distinct owner from Owner owner
join owner.cats cat
where cat.eyeColor = 'blue'
Qui est
Criteria c = session.createCriteria(Owner.class, "owner");
c.createAlias("owner.cats", "cat");
c.add(Restrictions.eq("cat.eyeColor", "blue");
c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
Essayez ceci:
DetachedCriteria dc = DetachedCriteria.forClass(Cat.class, "inner")
.add(Restrictions.eq("eyeColor", "blue"))
.add(Restrictions.eqProperty("inner.owner", "outer.id"));
session.createCriteria(Owner.class, "outer")
.add(Subqueries.exists(dc))
.list();
Cela peut utiliser index dans la base de données et ne fera pas une opération en mémoire distinct
comme dans la version de @JB Nizet (voir mon commentaire là-bas). L'indice sera:
CREATE INDEX idx_cat_owner_eyecolor ON Cat(fkOwner, eyeColor)
Pensez à l'opération distinct
(en SQL ou en mémoire) comme à une odeur de code. Il est rarement utilisé et de nombreux programmeurs novices l'utilisent pour résoudre le problème "pourquoi ai - je cette ligne deux fois". Il peut presque toujours être réécrit comme dans ce cas. Les cas d'utilisation, quand c'est nécessaire, sont peu nombreux.