web-dev-qa-db-fra.com

Sous-requête de critères d'hibernation

J'ai besoin de faire cette requête SQL avec des critères détachés:

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)

L'idée est d'obtenir les identifiants des jeux qui n'appartiennent pas à l'utilisateur. J'ai essayé comme 10 approches différentes avec détachéCriteria mais j'obtiens l'exception "MappingException: null" Le code devrait ressembler à:

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));

Définir également les projections pour renvoyer uniquement l'id des jeux.

Des idées? Je pense qu'Hibernate a du mal à rejoindre les requêtes sans alias. L'ajout d'alias fonctionne mais les résultats sont tout à fait faux.

23
Gonzalo

Vous devez ajouter un alias, comme suit:

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"));

Cela devrait aider

19
atrain

Vous avez besoin d'une projection et spécifiez quel attribut doit être mis en correspondance.

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));

J'espère que ça aide.

11
philip