Reputation: 901
I have a following query:
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
)
I am trying to convert this to Hibernate Criteria Query. I am really a rookie when it comes to HCQ. Any help would be very much appreciated.
Here is the ER mappings:
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
I made my query based on your answer,
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")));
Now I am getting this exception:
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)
Though it clearly states java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer, but I am not sure do I have explicitly mention dataType wherever I am dealing with the ID's in my query (shouldn't Hibernate be able to figure it out itself?).
Where am I going wrong ?
Upvotes: 2
Views: 6992
Reputation: 30803
untested
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();
Upvotes: 2