我的问题与这个老问题非常相似:Hibernate Criteria with self join但我需要一个非Hibernate特定的,干净的JPA解决方案来解决同样的问题。我目前使用Hibernate 4.3作为JPA提供程序,但是如果需要我可以更新它。我有以下实体:
现在我想创建一个查询,查找我针对特定对手玩的所有游戏并检索我们的分数。我得到了以下JPA查询:
String strQuery = "SELECT g, my_result, their_result FROM Game g JOIN g.results my_result JOIN g.results their_result WHERE my_result.player=:p1 AND their_result.player=:p2";
它似乎有效,但我想将其转换为Criteria API,而且在Criteria API方面我是一个完整的菜鸟。我开始关注:
Root<Game> game = query.from(Game.class);
Join<Game, GameResult> result_mine = game.join("results");
到目前为止,这么容易。但现在我不知道如何让result_theirs
加入这个部分。我试过以下:
Join<Game, GameResult> result_theirs = game.join("results");
result_mine.join( *what should I put here* , result_theirs);
//or:
Selection<Game> alias_game = game.alias("g");
Join result_theirs = result_mine.join(alias_game, "results"); //does not compile
//or:
Join result_theirs = result_mine.join(game.get("results")); //does not compile
//or:
Join<Game, GameResult> result_theirs = game.join("results");
result_mine.join(result_theirs); //does not compile
我错过了一些东西,但我不知道是什么,或者说我的方向错了。
那么,我做错了什么以及如何将JPA查询转换为Criteria API代码?
答案 0 :(得分:1)
你的第3次或者是正确的,除非你加入它两次
您的专家result_mine.join(result_theirs);
尝试加入GameResult
至GameResult
这是无法完成的,因为您的实体映射仅指定了如何将Game
加入GameResult
(但不是GameResult到GameResult)前者已由Join<Game, GameResult> result_theirs = game.join("results");
所以做下面的事情
CriteriaQuery<Tuple> query = cb.createTupleQuery();
Root<Game> game = query.from(Game.class);
Join<Game, GameResult> result_mine = game.join("results");
Join<Game, GameResult> result_theirs = game.join("results");
query
.multiselect(game, result_mine, result_theirs)
.where(
cb.equal(result_mine.get("player"),p1),
cb.equal(result_theirs.get("player"),p2)
);
List<Tuple> results = em.createQuery(query).getResultList();