Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

170
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda