2010-09-17 11 views
23

muszę zrobić zapytanie SQL z DetachedCriteria:Hibernate Kryteria podzapytaniu

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) 

Chodzi o to, aby uzyskać identyfikatory z gier, które nie są własnością użytkownika. Próbowałem jak 10 różnych podejść z DetachedCriteria ale pojawia się „Nieznane podmiot: zerowy” MappingException Kod powinien wyglądać następująco:

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

Ustawienie także występy wrócić tylko identyfikator gier.

Wszelkie pomysły? Myślę, że Hibernate ma problemy z dołączaniem zapytań bez aliasu. Dodawanie aliasu działa, ale wyniki są całkiem błędne.

+0

Nie odwzorowujesz powiązania między "grami" i "user_games" w swoich obiektach/mapowaniach? –

+0

user_games ma mapowanie do gier, ale nie viceversa. – Gonzalo

Odpowiedz

19

Trzeba dodać alias, co następuje:

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

To powinno pomóc

-3

Spróbuj

SELECT g.id FROM users_games ug join ug.game g 
WHERE NOT EXISTS (SELECT 1 FROM WHERE ug.user_id = 1) 
+5

Downvoting, ponieważ pytanie OP dotyczyło tego, jak to zrobić w Hibernate, a nie w surowym SQL. Również "Z GDZIEGO" byłby błąd składniowy w SQL. –

11

Trzeba projekcję i określa, który atrybut, który musi być dopasowany.

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

Mam nadzieję, że to pomaga.

Powiązane problemy