Hibernate Criteria与自我加入

时间:2015-06-24 14:38:20

标签: java mysql spring hibernate jpa

上周一直在学习Hibernate,Spring和JPA,并且一直试图为以下场景创建一个Criteria:

假设我有两张桌子:

游戏

  • ID

PlayedGame

  • ID
  • account_ref - >参考某些帐户表
  • game_id - >参考游戏

实体映射:

Game {

 @id
 Long id;

 @OneToMany(mappedBy = "game")
 Set<Player> players;

}

PlayedGame {

 @id
 Long id;

 Long account_ref;

 @ManyToOne
 @JoinColumn(name = "game_id", referencedColumnName = "id")
 Game game;
}

现在我想查询以下场景:   - 我想找到特定玩家(P)玩过的所有游戏,其中玩家(A)是其中的一部分。更具体地说,两个人属于同一个游戏

在SQL中,这可以用类似的东西来完成(查询应该是这样的):

SELECT DISTINCT p1.* FROM Player as p1 
INNER JOIN Player as p2 ON p1.game_id=p2.game_id 
WHERE p1.account_ref=P AND p2.account_ref=A 

这可以用Hibernate中的Criteria整齐地完成吗?

1 个答案:

答案 0 :(得分:1)

也许可以使用Hibernate的Criteria API,但不是直截了当的。

一个简单的案例需要相同的关联路径连接两次(一个用于 A ,一个用于 P ):

Criteria gameCriteria = ((HibernateEntityManager) em).getSession().createCriteria(Game.class);

Criteria playedGamesOfACriteria = gameCriteria.createCriteria("playedGames", "pga");
Criteria accountOfACriteria = playedGamesOfACriteria.createCriteria("account", "a");
accountOfACriteria.add(Restrictions.idEq(a.id));

Criteria playedGamesOfPCriteria = gameCriteria.createCriteria("playedGames", "pgp");
Criteria accountOfPCriteria = playedGamesOfPCriteria.createCriteria("account", "p");
accountOfPCriteria.add(Restrictions.idEq(p.id));

return gameCriteria.list();

由于HHH-879而无法工作。

但您可以使用JPA查询:

Query q = em.createQuery(
        "select g "
        + "from Game g "
        + "join g.playedGames pga "
        + "join pga.account a "
        + "join g.playedGames pgp "
        + "join pgp.account p "
        + "where a = ?1 and p = ?2"
);
q.setParameter(1, a);
q.setParameter(2, p);
return q.getResultList();

这甚至更少的代码。

另外:有些人认为Criteria API为deprecated