JPA Criteria API和两个连接在同一路径表达式上

时间:2017-07-01 22:09:05

标签: java jpa self-join

我的问题与这个老问题非常相似:Hibernate Criteria with self join但我需要一个非Hibernate特定的,干净的JPA解决方案来解决同样的问题。我目前使用Hibernate 4.3作为JPA提供程序,但是如果需要我可以更新它。我有以下实体:

  • 游戏,可以有多个结果条目,每个播放一个玩家一个
  • GameResult 游戏拥有并引用参与其中的玩家。它没有对拥有游戏 的反向引用 玩游戏的
  • 玩家

现在我想创建一个查询,查找我针对特定对手玩的所有游戏并检索我们的分数。我得到了以下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代码?

1 个答案:

答案 0 :(得分:1)

你的第3次或者是正确的,除非你加入它两次

您的专家result_mine.join(result_theirs);尝试加入GameResultGameResult这是无法完成的,因为您的实体映射仅指定了如何将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();