Критерии гибернации с несколькими соединениями и левым соединением - PullRequest
2 голосов
/ 03 февраля 2012

У меня есть следующий запрос:

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, где бы я ни имел дело с идентификаторами в своем запросе (разве Hibernate сам не сможет это выяснить?).

Куда я иду не так?

1 Ответ

2 голосов
/ 06 февраля 2012

непроверенных

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