Domanda
devo interrogare un Message
che si trova in un elenco fornito di Groups
e non è stato Deactivated
dall'utente corrente. Ecco alcuni pseudo codice per illustrare le proprietà e le entità:
class Message {
private int messageId;
private String messageText;
}
class Group {
private String groupId;
private int messageId;
}
class Deactivated {
private String userId;
private int messageId;
}
Ecco un'idea di quello che mi serve per interrogare, è l'ultima clausola AND che io non so come fare (ho fatto l'espressione NOT IN
composto). Filtrare i messaggi disattivata da userId può provocare molteplici messageIds, come posso controllare se quel sottoinsieme di righe non contiene il 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)
Nota: Il ...
è lì perché non so il numero di groupIds prima del tempo. Io li ricevo come Collection<String>
ne avrei bisogno di attraversare loro e aggiungerli alla JPQL dinamicamente.
Soluzione
Sembra che si stanno facendo un prodotto cartesiano nella query. È necessario disporre di una sottoquery per raggiungere il risultato. si può avere una query come questa:
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')