web-dev-qa-db-ja.com

Hibernate Criteriaサブクエリ

このSQLクエリをdetachedCriteriaで実行する必要があります。

SELECT g.id FROM games g
WHERE NOT EXISTS (
    SELECT 1 FROM users_games ug WHERE ug.user_id = 1 AND g.id = ug.game_id)

アイデアは、ユーザーが所有していないゲームからIDを取得することです。 detachedCriteriaを使用して10の異なるアプローチを試しましたが、「不明なエンティティ:null」を取得しましたMappingExceptionコードは次のようになります。

DetachedCriteria subquery = DetachedCriteria.forClass(UserGame.class, "ug")
   .add(Restrictions.eq("ug.user.id", 1))
   .add(Restrictions.eqProperty("ug.game.id","u.id"));
DetachedCriteria criteria = DetachedCriteria.forClass(Game.class, "g")
   .add(Subqueries.notExists(subquery));

プロジェクションも設定して、ゲームのIDのみを返します。

何か案は? Hibernateはエイリアスなしでクエリを結合するのに問題があると思います。エイリアスの追加は機能しますが、結果はかなり間違っています。

23
Gonzalo

次のように、エイリアスを追加する必要があります。

DetachedCriteria subquery = DetachedCriteria.forClass(UserGame.class, "ug")
   .addAlias("ug.user", "user")
   .add(Restrictions.eq("user.id", 1))
   .addAlias("ug.game", "game")
   .add(Restrictions.eqProperty("game.id","u.id"));

それは役立つはずです

19
atrain

プロジェクションが必要であり、照合する必要がある属性を指定します。

DetachedCriteria subquery = DetachedCriteria.forClass(UserGame.class, "ug")
.add(Restrictions.eq("ug.user.id", 1))
.add(Restrictions.eqProperty("ug.game.id","u.id"))
.setProjection(Projections.property("ug.game.id"));

DetachedCriteria criteria = DetachedCriteria.forClass(Game.class, "g")
.add(Property.forName("g.id").notIn(subquery));

お役に立てば幸いです。

11
philip