2017-07-01 60 views
1

我的問題是非常類似於這個老問題:Hibernate Criteria with self join但我需要一個非Hibernate特定的,乾淨的JPA解決方案相同的問題。我目前使用Hibernate 4.3作爲JPA提供程序,但如有必要,我可以更新它。我有以下實體:JPA Criteria API和兩個連接在相同的路徑表達式

  • 遊戲,它可以有很多結果條目,每每一個玩過
  • 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"; 

看來工作,但是我想它轉換成標準的API,並且我是一個完整的noob當涉及到標準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

你的第3或第是正確的,除非你是兩次參加其

你行result_mine.join(result_theirs);試圖加入GameResultGameResult不能做到爲您的實體映射唯一指定如何加入GameGameResult(但不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(); 
+0

謝謝!我認爲我錯過的一個事實是,調用'game.join(「results」)'不僅會返回連接對象,而且還會改變''遊戲根'本身,並且所有連續執行的連接都會修改它(什麼是合理的,我只是以某種方式沒有把握它)。現在我明白了(希望)。現在事情就像他們應該做的那樣 – Maciek