The final answer is :
in JPQL :
@NamedQuery(name = "core_user.findModuleAssociated", query = "select m from Module m where m.id in (select m1.id from Module m1 join m1.permissions p join p.user u where u.id = :userid) or m.id in (select m2.id from Module m2 join m2.permissions p2 join p2.group g join g.users u2 where u2.id = :userid)")
in criteria query :
List<Module> modules; CriteriaQuery<Module> query = cb.createQuery(Module.class); Root<Module> root_module = query.from(Module.class); Path path = root_module.get(Module_.id); Subquery<Integer> subquery = query.subquery(Integer.class); Root subRoot = subquery.from(Module.class); subquery.select(subRoot.get((Module_.id))); Join user1 = subRoot.join(Module_.permissions).join(Permission_.user); subquery.where(cb.equal(user1.get(User_.id), current.getId())); Subquery<Integer> subquery2 = query.subquery(Integer.class); Root subRoot2 = subquery.from(Module.class); subquery2.select(subRoot2.get((Module_.id))); Join user2 = subRoot2.join(Module_.permissions).join(Permission_.group).join(Group_.users); subquery2.where(cb.equal(user2.get(User_.id), current.getId())); query.where(cb.or(cb.in(path).value(subquery), cb.in(path).value(subquery2))); modules = getEntityManager().createQuery(query).getResultList();
Special thanks to Chris