【问题标题】:How to select a JPA Entity by whitelisting a property of its child Entity with the Criteria API?如何通过使用 Criteria API 将其子实体的属性列入白名单来选择 JPA 实体?
【发布时间】:2016-01-22 23:44:10
【问题描述】:

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

使用 Criteria API(而不是 JPQL),并给出

  1. 一张满是用户的桌子,每个人都有多辆汽车

    @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&lt;String&gt;

    Set<String> models = getThousandsOfModels();
    

如何选择至少有一个CarUsers,其modelmodels 集合中?

我已经阅读了许多 SO 答案,尝试了不同的方法(最有希望的方法似乎涉及使用 Expression&lt;Collection&lt;String&gt;&gt; 创建谓词,使用 .in() 等),但没有任何效果。

【问题讨论】:

  • 为什么要近距离投票?理解问题不需要其他数据。这里唯一缺少的是我没有的解决方案。我不需要代码,只要你知道答案,就给我指明正确的方向。
  • 出错的地方可能是“没有用”位,它危险地接近“它不起作用”。我会用代码而不是遥远的描述来说明你尝试了什么,对我来说,“in”子句确实是要走的路。
  • 开始用 JPQL 编写它。你会意识到你需要一个加入。所以在使用 Criteria 时你需要同样的东西:select distinct u from User u join u.cars c where c.model in :models。请注意,例如,Oracle 在 in 子句中限制为 1000 个元素。
  • @JBNizet 我试图避免这种情况(在阅读了在类似情况下避免加入的 SO 答案之后),但我越想它,我猜它是唯一的选择。然后我将其限制为 1000...谢谢,请随时将其发布为答案,以便我投票赞成
  • @JBNizet 它就像一个魅力。我现在只需要对其进行基准测试,但既然这是唯一的方法,谁在乎。还是谢谢

标签: java jakarta-ee jpa-2.0 criteria-api jpa-2.1


【解决方案1】:

下面的代码成功了:

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

【讨论】:

    猜你喜欢
    • 2018-07-04
    • 2013-11-09
    • 2016-12-17
    • 1970-01-01
    • 2014-11-20
    • 2013-06-10
    • 1970-01-01
    • 2015-06-24
    • 2015-02-15
    相关资源
    最近更新 更多