Найти пользователей с несколькими ролями в качестве критерия jpa - PullRequest
0 голосов
/ 13 марта 2020

Я пытаюсь найти всех пользователей, у которых есть все переданные роли, например:

List<Mitarbeiter> findByRoles(Set<MitarbeiterRolle> roles) {

    EntityManager em = getEntityManager();
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Mitarbeiter> cq = cb.createQuery(Mitarbeiter.class);
    Root<Mitarbeiter> mitarbeiter = cq.from(Mitarbeiter.class);

    List<Predicate> predicates = new ArrayList<>();
    for (MitarbeiterRolle role : roles) {
        Expression<MitarbeiterRolle> literal = cb.literal(role);
        predicates.add(literal.in(mitarbeiter.get("roles")));
    }
    cq.where(predicates.toArray(new Predicate[predicates.size()]));

    TypedQuery<Mitarbeiter> query = em.createQuery(cq);
    return query.getResultList();
}

, но это приводит к некоторому странному sql

from
    mitarbeiter mitarbeite0_ cross 
join
    mitarbeiter_roles roles1_ cross 
join
    mitarbeiter_roles roles2_ 
where
    mitarbeite0_.id=roles1_.mitarbeiter_id 
    and mitarbeite0_.id=roles2_.mitarbeiter_id 
    and (
        ? in (
            .
        )
    ) 
    and (
        ? in (
            .
        )
    )
2020-03-13 09:37:19 - WARN  - org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 42601
2020-03-13 09:37:19 - ERROR - org.hibernate.engine.jdbc.spi.SqlExceptionHelper - FEHLER: Syntaxfehler bei ».«

Есть идеи как этого добиться?

1 Ответ

0 голосов
/ 13 марта 2020

cb.isMember сделал трюк

default List<Mitarbeiter> findByRoles(Set<MitarbeiterRolle> roles) {

    EntityManager em = getEntityManager();
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Mitarbeiter> cq = cb.createQuery(Mitarbeiter.class);
    Root<Mitarbeiter> mitarbeiter = cq.from(Mitarbeiter.class);

    List<Predicate> predicates = new ArrayList<>();
    for (MitarbeiterRolle role : roles) {
        predicates.add(cb.isMember(role, mitarbeiter.get("roles")));
    }
    cq.where(predicates.toArray(new Predicate[predicates.size()]));

    TypedQuery<Mitarbeiter> query = em.createQuery(cq);
    return query.getResultList();
}
...