Can you please help me how to convert the following codes to using "in" operator of criteria builder? I need to filter by using list/array of usernames using "in".
I also tried to search using JPA CriteriaBuilder - "in" method but cannot find good result. So I would really appreciate also if you can give me reference URLs for this topic. Thanks.
Here is my codes:
//usersList is a list of User that I need to put inside IN operator CriteriaBuilder builder = getJpaTemplate().getEntityManagerFactory().getCriteriaBuilder(); CriteriaQuery<ScheduleRequest> criteria = builder.createQuery(ScheduleRequest.class); Root<ScheduleRequest> scheduleRequest = criteria.from(ScheduleRequest.class); criteria = criteria.select(scheduleRequest); List<Predicate> params = new ArrayList<Predicate>(); List<ParameterExpression<String>> usersIdsParamList = new ArrayList<ParameterExpression<String>>(); for (int i = 0; i < usersList.size(); i++) { ParameterExpression<String> usersIdsParam = builder.parameter(String.class); params.add(builder.equal(scheduleRequest.get("createdBy"), usersIdsParam) ); usersIdsParamList.add(usersIdsParam); } criteria = criteria.where(params.toArray(new Predicate[0])); TypedQuery<ScheduleRequest> query = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(criteria); for (int i = 0; i < usersList.size(); i++) { query.setParameter(usersIdsParamList.get(i), usersList.get(i).getUsername()); } List<ScheduleRequest> scheduleRequestList = query.getResultList();
The internal Query String is converted to below, so I don't get the records created by the two users, because it is using "AND".
select generatedAlias0 from ScheduleRequest as generatedAlias0 where ( generatedAlias0.createdBy=:param0 ) and ( generatedAlias0.createdBy=:param1 ) order by generatedAlias0.trackingId asc
Let's see it step by step: Create an instance of Session from the SessionFactory object. Create an instance of CriteriaBuilder by calling the getCriteriaBuilder() method. Create an instance of CriteriaQuery by calling the CriteriaBuilder createQuery() method.
You can define an ORDER BY clause with the orderBy method of the CriteriaQuery interface and the asc or desc method of the CriteriaBuilder interface. The following CriteriaQuery returns Book entities in the ascending order of their title attribute. List<Book> books = em. createQuery(cq).
public interface CriteriaBuilder. Used to construct criteria queries, compound selections, expressions, predicates, orderings. Note that Predicate is used instead of Expression<Boolean> in this API in order to work around the fact that Java generics are not compatible with varags. Since: Java Persistence 2.0.
Advertisements. The Criteria API is a predefined API used to define queries for entities. It is the alternative way of defining a JPQL query. These queries are type-safe, and portable and easy to modify by changing the syntax.
If I understand well, you want to Join ScheduleRequest
with User
and apply the in
clause to the userName
property of the entity User
.
I'd need to work a bit on this schema. But you can try with this trick, that is much more readable than the code you posted, and avoids the Join
part (because it handles the Join
logic outside the Criteria Query).
List<String> myList = new ArrayList<String> (); for (User u : usersList) { myList.add(u.getUsername()); } Expression<String> exp = scheduleRequest.get("createdBy"); Predicate predicate = exp.in(myList); criteria.where(predicate);
In order to write more type-safe code you could also use Metamodel by replacing this line:
Expression<String> exp = scheduleRequest.get("createdBy");
with this:
Expression<String> exp = scheduleRequest.get(ScheduleRequest_.createdBy);
If it works, then you may try to add the Join
logic into the Criteria Query
. But right now I can't test it, so I prefer to see if somebody else wants to try.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With