tags:

views:

54

answers:

3

Hi, i cannot use sorting on join tables. Let me explain;

i have three tables. users, roles and user_roles. my JPA entities are User, UserRole, UserRolePK, Role.

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

in fact the output that i want is: "SELECT * FROM user_roles ur JOIN users u ON u.ID = ur.UserID ORDER BY u.name;"

so i try to use hibernate criteria API.

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

The error is could not resolve property: pk.user.name of: models.UserRole

how can i use criteria API on join tables?

+1  A: 

Well, first of all I think we should see your entities mappings (Java Classes)

On the other hand, i'll assume your UserRole class has a reference to a User instance.

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

        User user;

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


    }

You should use createCriteria to navigate the 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();
}

The problem with this is that it will bring instances of UserRole, but you can navigate to User.

List<UserRole> userRoles = getRolesWithUser();

for (UserRole role:userRoles){

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

Take a look at the Criteria API. Its always helpful !

Tom
In user_roles table UserID and RoleID columns are primary keys. So i used embedded key and additional Class (UserRolePK) for it.UserRolePK has correct mapping.
Fırat KÜÇÜK
A: 

quite easy just use createCriteria on the associations:

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

This would join two tables for the Entites User and their associated Collection "roles". and would return all users which have a role associated with themselves called "test".

hope that helped

smeg4brains
There is no many to many relation property like roles in User entity. Instead I used UserRole entity.
Fırat KÜÇÜK
+1  A: 

If a class references other classes you can not simply access their properties in Restrictions and Orders. If will have to create an alias for the references objects and then use the alias to define Restrictions and Orders on the other objects.

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

The alias definitions will create a join with the tables of the other classes. Only properties that are directly mapped to the table of the class or an alias can be used in Restrictions or Orders. If your class contains components they can be accessed directly without an alias.

Reboot
seems good but it doesn't worked.Unknown column 'a2x2_.Name' in 'order clause'and this is the sql query that was generated by criteria API.__ "select this_.RoleID as RoleID614_0_, this_.UserID as UserID614_0_ from user_roles this_ order by a2x2_.Name asc" __
Fırat KÜÇÜK
Maybe there is something wrong with the mapping. Creating an alias should normally join the table, if the property is a many-to-one relationship. Your table graphics does not contain any relationsships. Maybe you should add them or add the mapping to the question.
Reboot