2009-05-05 9 views
3

Ich habe Probleme, eine Abfrage für die folgenden Domain-Klassen schreiben:Grails query association Problem

class Person { 
    static hasMany = [memberships: Membership] 
} 

class Membership { 

    static belongsTo = [person: Person, group: Group] 

    Date joinDate = new Date(); 
    Group group; 
    Person person; 
} 

class Group { 
    static hasMany = [memberships: Membership] 
} 

Grundsätzlich möchte ich alle Personen zu finden, die zu einer Liste von Gruppen gehört (Sagen wir Gruppen-IDs (1,2) sind Der Trick hier ist, dass die Person ein Mitglied beider Gruppen sein muss.Ich würde eine Kriterienabfrage bevorzugen, aber HQL ist auch ok.

Beachten Sie, dass die Abfrage mit etwas wie group.id in (1,2) wird nicht funktionieren, weil es irgendwelche sein kann der Gruppen, nicht beide

+0

Ich habe Zweifel an Ihrer Zuordnung, ist es richtig oder falsch? –

+0

Ich denke, es ist richtig, war vor langer langer Zeit ... –

+0

Ok, ich habe versucht, Domänen mit Ihren Daten zu erstellen, aber es zeigte einige Fehler, jedenfalls ist es in Ordnung, hoffe dein Problem ist gelöst –

Antwort

1

Das ist mein einfacher HQL Ansatz ist:

Person.executeQuery("FROM Person x WHERE x IN (SELECT m.person from Membership m WHERE m.group = :group1) AND x IN (SELECT m.person from Membership m WHERE m.group = :group2)", [ group1: Group.get(1), group2: Group.get(2) ]) 

Prost

+0

Tks, ich überkompliziert id: P –

+0

Übrigens ist es in Kriterien nicht machbar, weil, wenn ich Mitgliedschaftsvereinigung mehrfach abfrage, ich mit einem Hibernate "doppelten Verband" Problem beende. –

0

Vielleicht brauchen Sie keine Abfrage. In der Personenklasse ist Mitgliedschaften eine Liste von Mitgliedschaftsobjekten. Sie können feststellen, ob sich ein Objekt in einer Collection (Liste) befindet, ohne eine Abfrage durchzuführen. So etwas sollte den Job machen.

if(Person.memberships.contains(Membership.findByPersonAndGroup(person1,group1)) && Person.memberships.contains(Membership.findByPersonAndGroup(person1,group2))){ 
    ...do something... 
} 

Wahrscheinlich ist die andere Lösung einfacher, aber ich denke, das ist nur eine weitere Option.

Prost

Groovy Collections

+0

In Ihrem Beispiel ist das Objekt Person eine Klasse; Ich kann die Klasse selbst nicht abfragen, ich brauche eine Instanz der Person, um ihre Mitgliedschaftssammlung zu überprüfen. –

0

Interessante Problem. Ich bin mir nicht sicher, ob die vorherigen Lösungen generisch für die Anzahl der übereinstimmenden Gruppen sind - in den Fällen, in denen es bisher auf 2 festgesetzt wurde, denke ich. Obwohl es wahrscheinlich einen Weg gibt, sie variabel zu machen.

Ein anderer Weg, die ich hier auf der grails Messageboard beschreiben - http://www.nabble.com/has-many-through-relationship-query---GORM--td23438096.html

Einschließlich Kommentar des Autors, Robert Fischer, der "Grails Persistence mit GORM und GSQL".

@chadsmall

0

Hier ist ein weiterer Ansatz, die programmatisch mit vermeidet Unterabfragen zu Ihrer WHERE-Klausel anhängen:

Abfrage:

SELECT count(person.id) AS numPeople, person 
FROM Person as person 
INNER JOIN 
person.memberships AS mships 
WITH mships.group.id IN (:groupIds) 
GROUP BY person.id 
HAVING COUNT(person.id) = (:numOfGroupIds) 

Und einige Beispielwerte:

[ 
    groupIds: [8,9,439,86843] 
    numOfGroupIds: 4 
] 

Der Teil dieser Abfrage bis zur GROUP BY ergreift alle th Die Leute, die übereinstimmen beliebig der Gruppen. Wenn Sie dann nach Personen gruppieren und die Anzahl der Ergebnisse mit der Anzahl der Gruppen in der Liste vergleichen, können Sie überprüfen, ob diese Person ein Mitglied aller angegebenen Gruppen ist.