I am trying to build a specifications to predicate subquery for the below query. Select u.* from User u where u.login in (select ur.role_id from userRoles ur where ur.role_Id = roleId).
till now this is the part I have built
public static Specification<User> userRoleId(String roleId) {
return new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
//return builder.equal(root.<LocalDate> get("scheduledDisbursementDate"), scheduledDisbursementDate);
Subquery<UserRole> subquery = query.subquery(UserRole.class);
Root<UserRole> subqueryRoot = subquery.from(UserRole.class);
subquery.select(subqueryRoot);
Predicate roleIdList = builder.equal(subqueryRoot.get("roleId"), roleId);
subquery.select(subqueryRoot).where(roleIdList);
return builder.exists(subquery);
}
};
}
Can you please help me out to link the subquery with main query.
Note: There are no joins defined in the Entity classes. evrything should be done through subquerys only
Found Answer
first predicate will join UserRole userId column with and User table login column. Second predicate will filter the condition based on roleId.
public static Specification<User> userRoleId(String roleId) {
return new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
Subquery<UserRole> subquery = query.subquery(UserRole.class);
Root<UserRole> subqueryRoot = subquery.from(UserRole.class);
subquery.select(subqueryRoot);
Predicate userIdPredicate = builder.equal(subqueryRoot.get("userId"), root.<String> get("login"));
Predicate rolePredicate = builder.equal(subqueryRoot.get("roleId"), roleId);
subquery.select(subqueryRoot).where(userIdPredicate, rolePredicate);
return builder.exists(subquery);
}
};
}