具有多个连接和左连接的Hibernate Criteria

时间:2012-02-02 23:35:13

标签: sql hibernate hibernate-criteria

我有以下查询:

SELECT users.user_id as user_id , users.USERNAME, users.FIRSTNAME, users.LASTNAME, roles.name AS role_name
    FROM user_role userrole
    JOIN user users ON userrole.user_id = users.user_id
    JOIN role roles ON userrole.role_id  = roles.role_id
    WHERE userrole.role_id IN (
        SELECT  distinct(role.role_id) FROM perm p
            JOIN function_code fc ON p.function_code_id = fc.function_code_id
            JOIN role role ON p.role_id  = role.role_id
            JOIN service service ON service.service_id = fc.service_id AND service.name = '<myservice>'
            LEFT JOIN datapolicy dp ON p.datapolicy_id = dp.datapolicy_id AND p.role_id = dp.role_id
    )

我正在尝试将其转换为Hibernate Criteria Query。在HCQ问题上,我真是个新秀。非常感谢任何帮助。

这是ER映射:

user --> role (one to many)
role --> perm (one to many)
perm --> function_code  (one to one) 
perm --> datapolicy  (one to one)
service --> function_code (one to many)
role  --> datapolicy (one to many)


@Firo
我根据你的答案提出了我的问题,

sessionFactory.getCurrentSession().createCriteria(User.class, "user")
    .createAlias("roles", "role").add(
        Subqueries.in("role.id", DetachedCriteria.forClass(Role.class).
        createCriteria("securityPermissions").createCriteria("functionCode")
        .createCriteria("serviceName").add(Restrictions.eq("name", serviceName))
        .setProjection(Projections.distinct(Projections.id())))
    ).setProjection(Projections.projectionList().add(Projections.property("id"))
    .add(Projections.property("user.username")).add(Projections.property("user.firstname"))
    .add(Projections.property("user.lastname")).add(Projections.property("role.name")));

现在我得到了这个例外:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    org.hibernate.type.IntegerType.set(IntegerType.java:64)
    org.hibernate.type.NullableType.nullSafeSet(NullableType.java:154)
    org.hibernate.type.NullableType.nullSafeSet(NullableType.java:136)
    org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1728)
    org.hibernate.loader.Loader.bindParameterValues(Loader.java:1699)
    org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1589)
    org.hibernate.loader.Loader.doQuery(Loader.java:696)
    org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    org.hibernate.loader.Loader.doList(Loader.java:2228)
    org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
    org.hibernate.loader.Loader.list(Loader.java:2120)
    org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:118)
    org.hibernate.impl.SessionImpl.list(SessionImpl.java:1596)
    org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)

虽然它明确指出 java.lang.ClassCastException:java.lang.String无法强制转换为java.lang.Integer ,但我不确定我是否在任何地方都明确提到dataType在我的查询中使用ID(不应该让Hibernate自己弄明白吗?)。

我哪里错了?

1 个答案:

答案 0 :(得分:2)

未测试

session.createCriteria(User.class, "user")
    .createAlias("Roles", "role");
    .add(Subqueries.In("role.id", DetachedCriteria.for(Role.class)
        .createCriteria("functions")
            .createCriteria("services")
                .add(Restrictions.eq("name", "<myservice>")
        .setProjection(Projections.distinct(Projections.id()))
    )
    .setProjection(Projections.list()
        .add(Projections.property("id"))
        .add(Projections.property("Name"))
        ...
        .add(Projections.property("role.id"))
        .add(Projections.property("role.name"))
    )
    .list();