2009-08-14 12 views
4

Je voudrais utiliser l'API Criteria d'Hibernate pour précisément ce que tout le monde dit être probablement son cas d'utilisation le plus probable, en appliquant des critères de recherche complexes. Le problème est que la table sur laquelle je veux interroger n'est pas entièrement composée de valeurs primitives, mais partiellement d'autres objets, et j'ai besoin de faire une requête par rapport aux identifiants de ces objets.L'API Criteria d'Hibernate ne supporte toujours pas les relations imbriquées

J'ai trouvé this article il y a 2 ans ce qui suggère que ce n'est pas possible. Voici comment je l'ai essayé en vain, il y a d'autres aspects d'Hibernate où je sais où cette sorte de notation par points est supportée dans les littéraux de chaîne pour indiquer l'imbrication d'objet.

if (!lookupBean.getCompanyInput().equals("")) { 
     criteria.add(Restrictions.like("company.company", lookupBean.getCompanyInput() + "%")); 
    } 

EDIT:

Voici mon code pour accomplir correctement pris en compte ce que je tentais ci-dessus, en utilisant la suggestion de la première réponse ci-dessous; Notez que je suis même à l'aide d'un appel createCriteria supplémentaire à l'ordre sur un attribut dans un autre objet associé/table:

if (!lookupBean.getCompanyValue().equals("")) { 
    criteria.createCriteria("company").add(
      Restrictions.like("company", lookupBean.getCompanyValue() + "%")); 
} 

List<TrailerDetail> tdList = 
     criteria.createCriteria("location").addOrder(Order.asc("location")).list(); 

Répondre

7

Pas tout à fait sûr de vous suivre votre exemple, mais il est certainement possible de spécifier les conditions de filtre sur une entité associée , simplement en imbriquant Critères objets pour former un arbre. Par exemple, si j'ai une entité appelée ordre avec plusieurs à une relation avec un utilisateur entité, je peux trouver toutes les commandes pour un utilisateur nommé Fred avec une requête comme ceci:

List<Order> orders = session.createCriteria(Order.class) 
    .createCriteria("user") 
     .add(eq("name", "fred")) 
    .list(); 

Si vous parlez d'une entité qui a une relation avec elle-même, cela devrait aussi fonctionner. Vous pouvez également remplacer "nom" par "id" si vous avez besoin de filtrer sur l'ID d'un objet associé.

+2

+1. Toutefois, vous devez être prudent avec les ID. En fonction du mappage, il n'est peut-être pas nécessaire (voire légal) de créer des critères imbriqués pour interroger les associations par ID. Par conséquent, dans l'exemple ci-dessus vous utiliseriez 'session.createCriteria (Order.class) .add (eq (" user.id ", 25)). List()' – ChssPly76

+0

Et j'allais ajouter que si vous avez une référence à l'objet associé dans votre code Java, vous pouvez également transmettre l'objet entité lui-même en tant qu'argument à l'appel Restrictions.eq (par exemple Restrictions.eq ("utilisateur", utilisateur)) au lieu de l'ID. Vous pouvez facilement obtenir une telle référence sans payer de pénalité de performance en utilisant Session.load (User.class, ). –

+0

Merci votre suggestion a fonctionné. N'avait pas de référence à l'objet associé. Je pourrais modifier ma question pour indiquer le code de remplacement qui a fonctionné. Mais comment nicheriez-vous plus d'un critère si vous en aviez besoin? Je n'en ai pas besoin mais cela pourrait être problématique. Si vous avez seulement besoin d'en nicher un, ce devrait probablement être la dernière chose que vous clouez sur les critères d'origine. En tout cas merci! Je viens de remplacer des douzaines de lignes de code construisant une requête HQL avec un StringBuffer, à environ moins de 10 lignes. –

Questions connexes