如何通过使用标准 API 将其子实体的 属性 列入白名单来 select JPA 实体?

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

我遇到了以下假设性问题:

使用条件API(而不是JPQL),并给定

  1. 一个 table 充满了 用户,每个用户有多个 汽车

    @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. 一个 Set<String> 包含 车型:

    Set<String> models = getThousandsOfModels();
    

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

我读过很多 SO 答案,尝试了不同的方法(最有希望的似乎涉及使用 Expression<Collection<String>>、使用 .in() 等创建谓词)但没有任何效果。

下面的代码起到了作用:

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