简体   繁体   中英

JPA CriteriaBuilder with junction table

How can the sql expression below be expressed using CriteriaBuilder?

select * from Ref where prac_id = (select prac_id from loc l join staff_loc sl where sl.loc = l.id and sl.pracstaff_id = 123)

Model Classes

@Entity
public class Ref {
    private Long id;
    private Prac prac;
}

@Entity
public class Loc {
    Long id;
    @ManyToOne
    Prac prac;
    @ManyToMany
    Set<PracStaff> pracStaff;
}

@Entity
public class Prac {
    Long id;
    @OneToMany
    Set<Loc> locs;
}

@Entity
public class PracStaff {
    Long id;
    @ManyToMany
    Set<Loc> locs;
}
  • There's a join table that maps Loc to PracStaff; it has two columns: pracstaff_id and loc_id
  • A Loc can belong to only one Prac.

What I'm trying to get is all Ref objects that have a PracStaff with id 123 using CriteriaBuilder.


Here's the solution I got to work though I haven't tested it thoroughly. Using

Expression<Collection<PracStaff>>

to return the collection is what I was missing

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Ref> criteriaQuery = criteriaBuilder.createQuery(Ref.class);
Root<Ref> from = criteriaQuery.from(Ref.class);
criteriaQuery.select(from);

Subquery<Prac> subquery = criteriaQuery.subquery(Prac.class);
Root<Loc> fromLoc = subquery.from(Loc.class);
Expression<Collection<PracStaff>> pracStaffInLoc = fromLoc.get("pracStaff");
subquery.where(criteriaBuilder.isMember({pracStaffObj}, pracStaffInLoc));
subquery.select(fromLoc.<Prac>get("prac"));     
Path<Prac> specialist = from.get("{field in Ref class}");
Predicate p = criteriaBuilder.equal(specialist, subquery);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM