2010-03-28 6 views
0

Je dois interroger un Message qui est dans une liste fournie de Groups et n'a pas été Deactivated par l'utilisateur actuel. Voici quelques pseudo-code pour illustrer les propriétés et les entités:Aide avec la requête JPQL

class Message { 
    private int messageId; 
    private String messageText; 
} 

class Group { 
    private String groupId; 
    private int messageId; 
} 

class Deactivated { 
    private String userId; 
    private int messageId; 
}

Voici une idée de ce que je dois interroger pour, il est le dernier et l'article que je ne sais pas comment faire (j'ai fait la composé NOT IN expression). Filtrer les messages désactivés par userId peut entraîner plusieurs messages, comment puis-je vérifier si ce sous-ensemble de lignes ne contient pas le messageId?

SELECT msg FROM Message msg, Group group, Deactivated unactive 
WHERE 
    group.messageId = msg.messageId 
    AND (group.groupId = 'groupA' OR group.groupId = 'groupB' OR ...) 
    AND ('someUserId', msg.messageId) NOT IN (unactive.userId, unactive.messageId)

Note: Le ... est là parce que je ne sais pas le nombre de groupids à l'avance. Je les reçois en tant que Collection<String> donc je vais devoir les traverser et les ajouter dynamiquement au JPQL.

+0

Pourriez-vous clarifier le problème (btw, vous pourriez utiliser 'AND group.groupId IN (: list)' au lieu de plusieurs 'OR')? –

+0

Merci pour la pointe pour réduire les conditions de branchement. Le problème est '('someUserId', msg.messageId) NOT IN (unactive.userId, unactive.messageId)' est invalide - Je ne sais pas comment construire cette partie de la requête. Peut-être qu'une sous-requête est en ordre? – Lightbeard

Répondre

1

Il semble que vous fassiez un produit cartésien dans votre requête. Vous devez avoir une sous-requête pour atteindre votre résultat. vous pouvez avoir une requête comme ceci:

SELECT msg 
FROM Message msg, Group grp 
WHERE msg.id = grp.msgId 
     AND grp.id IN (...) 
     AND msg.id NOT IN (SELECT msgId FROM Desactivated WHERE userId = 'uid')