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.