2010-09-02 4 views
6

Je ne peux pas utiliser le tri sur les tables de jointure. Laisse-moi expliquer;Critères d'hibernation api problème de table de jointure

J'ai trois tables. utilisateurs, rôles et user_roles. mes entités JPA sont User, UserRole, UserRolePK, Role.

|User |  | UserRole |  | UserRolePK |  | Role | 
|--------|  |----------|  --------------  -------- 
|id  |  | pk  |  | user  |  | id | 
|name |      | role  |  | name | 

en fait la sortie que je veux est: "SELECT * FROM user_roles ur utilisateurs u ON Inscrivez-u.ID = ur.UserID ORDER BY u.name;" Donc j'essaie d'utiliser l'API des critères hibernate.

CriteriaImpl criteria = (CriteriaImpl) session.createCriteria(UserRole.class); 
criteria.addOrder(Order.asc("pk.user.name")); 
List userRoles = criteria.list(); 

L'erreur est ne pouvait pas résoudre la propriété: pk.user.name de: models.UserRole

Comment puis-je utiliser l'API de critères sur jointures de tables?

Répondre

9

Si une des références de classe d'autres classes vous ne pouvez pas accéder simplement leurs propriétés dans les restrictions et ordonnances. Vous devrez créer un alias pour les objets référencés, puis utiliser l'alias pour définir les restrictions et les commandes sur les autres objets.

Criteria criteria = (CriteriaImpl) session.createCriteria(UserRole.class); 
criteria.createAlias("pk", "a1"); 
criteria.createAlias("a1.user", "a2"); 
criteria.addOrder(Order.asc("a2.name")); 
List userRoles = criteria.list(); 

Les définitions d'alias créeront une jointure avec les tables des autres classes. Seules les propriétés directement mappées à la table de la classe ou à un alias peuvent être utilisées dans Restrictions ou Commandes. Si votre classe contient des composants, ils peuvent être accédés directement sans alias.

+0

semble bon mais cela n'a pas fonctionné. Colonne inconnue 'a2x2_.Nom dans la 'clause de commande' et c'est la requête sql qui a été générée par l'API de critères. __ "Sélectionnez this_.RoleID comme RoleID614_0_, this_.UserID comme UserID614_0_ à partir de user_roles this_ order par a2x2_.Name asc" __ –

+0

Peut-être que quelque chose ne va pas dans le mapping. Créer un alias devrait normalement rejoindre la table, si la propriété est une relation plusieurs-à-un. Vos graphiques de table ne contiennent aucune relation. Peut-être que vous devriez les ajouter ou ajouter le mappage à la question. – Reboot

1

Eh bien, tout d'abord je pense que nous devrions voir vos correspondances entités (Java Classes)

D'autre part, je vais prendre votre classe UserRole a une référence à une instance de l'utilisateur.

@Entity 
    @Table (name="UserRole") 
    public class UserRole{ 

     User user; 

     @OneToMany //correct mapping here 
     public User getUser(){return this.user;} 


    } 

Vous devez utiliser createCriteria pour naviguer dans le association.

public List<UserRole> getRolesWithUser(){ 
    Criteria userRoleCriteria = session.createCriteria(UserRole.class); 
    userRoleCriteria.createCriteria("user"); //joins the table. 
    userRoleCriteria.addOrder("user.name"); //adds order 

    return criteria.list(); 
} 

Le problème est qu'il apportera des cas de UserRole, mais vous pouvez naviguer à User.

List<UserRole> userRoles = getRolesWithUser(); 

for (UserRole role:userRoles){ 

    User user = role.getUser(); 
    //do something with role , user 
} 

Jetez un oeil à la Criteria API. C'est toujours utile!

+0

Dans la table user_roles, les colonnes UserID et RoleID sont des clés primaires. J'ai donc utilisé la clé intégrée et la classe supplémentaire (UserRolePK) pour cela.UserRolePK a un mappage correct. –

1

assez facile il suffit d'utiliser createCriteria sur les associations:

Criteria c=session.createCriteria(User.class) 
        .createCriteria("roles") 
        .add(Restrictions.eq("name","test") 
        .list(); 

Ce joindrait deux tables pour l'utilisateur et leurs Entités mises Collection associés « rôles ». et retournerait tous les utilisateurs qui ont un rôle associé à eux-mêmes appelé "test".

espoir qui a aidé

+0

Il n'y a pas beaucoup de propriétés de relation comme des rôles dans l'entité utilisateur. Au lieu de cela j'ai utilisé l'entité UserRole. –