【发布时间】:2013-10-12 02:22:21
【问题描述】:
如果我使用 Join 在条件查询中创建谓词,我将不会得到任何结果。当我使用Game 表作为根时,相同的谓词返回实体。
工作查询:
CriteriaQuery<Game> query = cb.createQuery(Game.class);
Root<Game> root = query.from(Game.class);
List<Predicate> predicates = new LinkedList<Predicate>();
if(!selectedPlatforms.isEmpty()) {
predicates.add(root.get(Game_.type).in(TypeConverter.convert(selectedPlatforms)));
}
if(!selectedCategories.isEmpty()) {
Join<Game, String> collection = root.join(Game_.categories);
predicates.add(collection.in(cb.literal(selectedCategories)));
}
if(!selectedGames.isEmpty()) {
predicates.add(cb.isTrue(root.get(Game_.name).in(selectedGames)));
}
query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
games = em.createQuery(query).getResultList();
查询无效:
CriteriaQuery<Hit> query = cb.createQuery(Hit.class);
List<Predicate> predicates = new LinkedList<>();
Date startDate = null;
Date endDate = null;
Root<Hit> hitRoot = query.from(Hit.class);
switch (time) {
case "Week":
startDate = new DateTime().withWeekOfWeekyear(timeValue).withDayOfWeek(DateTimeConstants.MONDAY).toDate();
endDate = new DateTime().withWeekOfWeekyear(timeValue+1).withDayOfWeek(DateTimeConstants.SUNDAY).toDate();
}
predicates.add(cb.and(cb.greaterThanOrEqualTo(hitRoot.<Date>get("hitDate"), startDate), cb.lessThanOrEqualTo(hitRoot.<Date>get("hitDate"), endDate)));
Join<Hit, Game> gameJoin = hitRoot.join("game", JoinType.LEFT);
if(!selectedPlatforms.isEmpty()) {
predicates.add(gameJoin.get(Game_.type).in(TypeConverter.convert(selectedPlatforms)));
}
if(!selectedCategories.isEmpty()) {
Join<Game, String> collection = gameJoin.join(Game_.categories);
predicates.add(collection.in(cb.literal(selectedCategories)));
}
if(!selectedGames.isEmpty()) {
predicates.add(cb.isTrue(gameJoin.get(Game_.name).in(selectedGames)));
}
query.groupBy(hitRoot.get("hitDate"), hitRoot.get("shop"));
query.orderBy(cb.asc(hitRoot.get("shop")));
query.where(predicates.toArray(new Predicate[predicates.size()]));
List<Hit> results = em.createQuery(query).getResultList();
以下部分负责不返回任何匹配实体。刚刚应用于Root 而不是Join 的相同部分就像在第一个查询中一样返回machting 实体。没有这部分,其他一切都在工作。
if(!selectedGames.isEmpty()) {
predicates.add(cb.isTrue(gameJoin.get(Game_.name).in(selectedGames)));
}
【问题讨论】:
-
你能排除原因不在 JodaTime 谓词中吗?你试过没有它吗?添加实体定义中使用的映射来定义连接关系
-
如果我注释掉分组和 JodaTime 谓词,结果仍然是一样的。
-
不工作和结果还是一样是什么意思?
-
这两个查询的区别在于,第二个查询使用了
Game表作为连接,但该表上的谓词仍然相同。谓词正在构建,但没有返回与这些谓词匹配的实体。在第一个查询中,有合适的实体。 -
但是第二个查询有额外的限制:游戏必须被点击引用,它本身有日期限制。那么,您确定第一个查询返回的游戏与满足这些日期限制的命中相关联吗?
标签: java sql jpa criteria-api