tag etiquetas ejemplos java jpa persistence criteriaquery

etiquetas - taglib java



JPA: encuentre todos los artĂ­culos que tienen un conjunto comĂșn de etiquetas (1)

Tengo las siguientes entidades:

@Entity public class Article{ @Id private String id; @ManyToMany(cascade = CascadeType.PERSIST) private Set<Tag> tags; //non-relevant code } @Entity public class Tag{ @Id private String id; @Basic @Column(nullable = false, unique = true, length = 32) private String name; //non-relevant code }

¿Cómo puedo encontrar eficientemente todas las entidades de Article que tienen un set común de etiquetas?

El enfoque ingenuo es encontrar todos los artículos que pertenecen a cada tag y luego devolver la intersection de todos los conjuntos de artículos. Algo como:

public Set<Article> findByTags(Set<Tag> tags){ Set<Article> result = new HashSet<>(); if(tags.isEmpty()){ return result; } Iterator<Tag> i = tags.iterator(); result.addAll(i.next().getArticles()); while(i.hasNext() && !result.isEmpty()){ result.retainAll(i.next()); } return result; }

Mi pregunta es " ¿Hay una manera más eficiente de hacer esto, que no requiera buscar posiblemente todos los artículos de la base de datos, como este? Tal vez a través de una consulta JPQL o usando el CriteriaBuilder (nunca lo he usado antes)"


select a from Article a where :numberOfTags = (select count(distinct tag.id) from Article a2 inner join a2.tags tag where tag in :tags and a = a2)

Esto básicamente cuenta las etiquetas de los artículos que son etiquetas en el conjunto de etiquetas aceptado, y si el número de dichas etiquetas es igual al tamaño del conjunto de etiquetas aceptado (lo que significa que todas las etiquetas en el conjunto son etiquetas del artículo) , devuelve el artículo.