Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

169
Vistas
Ordene el conjunto de resultados según el tamaño de la colección en una entidad

Considere las siguientes entidades:

 class Team { private String name; @OneToMany private Set<Employee> employees; } class Employee { private String name; @OneToMany private Set<Skill> skills; } class Skill { private String name; private boolean active; private Date expiryDate; }

Necesito ordenar el conjunto de resultados de Teams de modo que el equipo con el máximo de habilidades activas y vigentes sea el primero. Estoy usando Spring Boot Specification & CriteriaQuery para filtrar equipos en diferentes campos. Hasta ahora tengo el siguiente código que no funciona como se esperaba.

 public class TeamSpecs implements Specification<Team> { @Override public Predicate toPredicate(Root<Team> root, CriteriaQuery<?> cq, CriteriaBuilder cb) { Order o = cb.desc(cb.sum(cb.size(root.join("employees").get("skills"))); cq.orderBy(o)); return cb.like(cb.equal(root.get("name"), "%" + value + "%")); } }

¿Algo que me esté perdiendo aquí? Por favor recomiende

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Para que esto funcione, primero debe unir sus tablas, luego filtrar las entradas, agruparlas y luego ordenarlas.

Entonces su consulta SQL debería verse así:

 select team.* from Team team inner join employee inner join skill where skill.active = true and skill.expiryDate > today group by team.name order by count(skill.name) desc

Nota al margen :
Usar una Specification en este caso no es lo que desea hacer, porque no representan una Consulta completa, sino una declaración o parte de una consulta, que se usa en múltiples consultas.

Usando la consulta de criterios JPA:

 public List<Team> getTeamsWithActiveSkills() { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Team> cq = cb.createQuery(Team.class); Root<Team> root = cq.from(Team.class); Join<Team, Employee> employees = root.join("employees"); Join<Team, Skill> skills = employees.join("skills"); Predicate isActive = cb.isTrue(skills.get("active")); Predicate isNonExpired = cb.greaterThan(skills.get("expiryDate"), LocalDate.now()); cq.where(isActive, isNonExpired).groupBy(root.get("name")); Order order = cb.desc(cb.count(skills)); cq.orderBy(order); return em.createQuery(cq).getResultList(); }

Dado que personalmente considero que la consulta de criterios es difícil de leer y poco intuitiva, podría usar Querydsl como alternativa.

Usando Querydsl:

 public List<Team> getTeamsWithActiveSkills() { QTeam team = QTeam.team; QEmployee employee = QEmployee.employee; QSkill skill = QSkill.skill; JPQLQuery<Team> query = from(team).join(team.employees, employee).join(employee.skills, skill); query = teamJPQLQuery.where(skill.active.isTrue().and(skill.expiryDate.gt(LocalDate.now()))); query = query .groupBy(team.name); query = query .orderBy(skill.name.count().desc()); return query.fetch(); }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda