【问题标题】:hibernate criteria api join table problemhibernate条件api连接表问题
【发布时间】:2010-09-02 13:29:43
【问题描述】:

我不能对连接表使用排序。让我解释一下;

我有三张桌子。用户、角色和 user_roles。 我的 JPA 实体是 User、UserRole、UserRolePK、Role。

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

事实上,我想要的输出是: "SELECT * FROM user_roles ur JOIN users u ON u.ID = ur.UserID ORDER BY u.name;"

所以我尝试使用休眠条件 API。

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

错误是 无法解析属性:pk.user.name of:models.UserRole

如何在连接表上使用条件 API?

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

    如果一个类引用了其他类,您不能简单地访问它们在 Restrictions and Orders 中的属性。您必须为引用的对象创建一个别名,然后使用该别名在其他对象上定义限制和顺序。

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

    别名定义将创建与其他类的表的连接。只有直接映射到类表或别名的属性才能在 Restrictions 或 Orders 中使用。如果您的类包含组件,则无需别名即可直接访问它们。

    【讨论】:

    • 看起来不错,但没有用。 “订单子句”中的未知列“a2x2_.Name”,这是由条件 API 生成的 sql 查询。 __“选择 this_.RoleID 作为 RoleID614_0_,this_.UserID 作为 UserID614_0_ from user_roles this_ order by a2x2_.Name asc” __
    • 可能映射有问题。如果属性是多对一关系,则创建别名通常应该加入表。您的表格图形不包含任何关系。也许您应该添加它们或将映射添加到问题中。
    【解决方案2】:

    很简单,只需在关联上使用 createCriteria:

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

    这将为实体用户及其关联的集合“角色”连接两个表。并将返回所有与自己关联的角色称为“test”的用户。

    希望有所帮助

    【讨论】:

    • 用户实体中没有像角色这样的多对多关系属性。相反,我使用了 UserRole 实体。
    【解决方案3】:

    嗯,首先我认为我们应该看到您的实体映射(Java 类)

    另一方面,我假设您的 UserRole 类引用了一个 User 实例。

       @Entity
        @Table (name="UserRole")
        public class UserRole{
    
            User user;
    
            @OneToMany //correct mapping here
            public User getUser(){return this.user;}
    
    
        }
    

    您应该使用createCriteria 导航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();
    }
    

    这样做的问题是它会带来UserRole 的实例,但您可以导航到User

    List<UserRole> userRoles = getRolesWithUser();
    
    for (UserRole role:userRoles){
    
       User user = role.getUser();
       //do something with role , user
    }
    

    看看Criteria API。它总是有帮助的!

    【讨论】:

    • 在 user_roles 表中,UserID 和 RoleID 列是主键。所以我使用了嵌入式密钥和附加类(UserRolePK)。UserRolePK 有正确的映射。
    猜你喜欢
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-30
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    相关资源
    最近更新 更多