简体   繁体   中英

How to select a JPA Entity by whitelisting a property of its child Entity with the Criteria API?

I'm stuck with the following hypothetical problem:

Using the Criteria API (and not JPQL ), and given

  1. A table full of users , each one having multiple cars

     @Entity public class User { @Id private Long id; @OneToMany private Set<Car> cars; } 
     @Entity public class Car { @Id private Long id; private String model; } 
  2. A Set<String> containing car models :

     Set<String> models = getThousandsOfModels(); 

How can I select the User s having at least one Car whose model is in the models Set ?

I've read many SO answers, tried different ways (the most promising seemed to involve creating predicates with Expression<Collection<String>> , using .in() etc.) but nothing worked.

The following code did the trick:

Set<String> models = getHundredsOfModels(); 
if (models.size()>1000) throw new TooManyResultsException(); // Oracle limit

CriteriaBuilder cb          = em.getCriteriaBuilder();
CriteriaQuery<User> cQuery  = cb.createQuery(User.class);
Root<User> user             = cQuery.from(User.class);
List<Predicate> predicates  = new ArrayList<Predicate>();

//  This lines are the trick  ------------------------------------------
Join<User, Car> usersCars   = user.join("cars", JoinType.INNER);
Predicate p                 = usersCars.<String>get("model").in(models);
// ---------------------------------------------------------------------    

predicates.add(p);
cQuery.select(user).where(predicates.toArray(new Predicate[predicates.size()]));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM