digiarnie
digiarnie

Reputation: 23425

Elegant way of finding intersection of Many-to-Many entities using Play

Let's say I have a Student entity like this implemented using the Play Framework's Model class:

@Entity
public class Student extends Model {

    public String name;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "student_subject",
        joinColumns = {@JoinColumn(name = "student_id", referencedColumnName = "id")},
        inverseJoinColumns = {@JoinColumn(name = "subject_id", referencedColumnName = "id")})
    public List<Subject> subjects;

    ...
}

And a Subject looks like this:

@Entity
public class Subject extends Model {

    public String name;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "student_subject",
        joinColumns = {@JoinColumn(name = "subject_id", referencedColumnName = "id")},
        inverseJoinColumns = {@JoinColumn(name = "student_id", referencedColumnName = "id")})
    public List<Student> students;

    ...
}

Is there a simple way using Play! (if not, what is the best way to do it otherwise) to find all students that have at least one subject in common with a particular student?

So let's say:

I was hoping to do something as simple as this:

List<Student> students = Student.find("subjects in ? and id <> ?", studentA.subjects, studentA.id).fetch();

which I would expect to return two Students: B and D (since Students B and D have at least one subject in common with Student A as passed in via the query above).

Upvotes: 3

Views: 847

Answers (1)

JB Nizet
JB Nizet

Reputation: 692013

Here is the JPQL query I would use :

select s from Student s
inner join s.subjects subject
where subject in (:subjectsOfStudentA)
and s != :studentA

It's pretty similar to your query, but you need a join to be able to use the subjects of the searched students in the where clause.

Upvotes: 5

Related Questions