Here's an example of the syntax I'm using for another condition (where ANY of the tags appear on the document via a FK).
predicates.add(root.join(Document_.tags).in({ pseudocode array of tags }));
I'm trying to come up with a similar predicate, but where the Document entity has ALL of the tags listed in the filter.
if all the tags listed in the filters are all the tags that exist you could try this
predicates.add(criteriaBuilder.equal(criteriaBuilder.size(root.get(Document_.tags)),
countOfAllTheTags));
or, if the tags in the filter are a subset of all of the tags, try this one
predicates.addAll(Stream.of(tags)
.map(tag -> criteriaBuilder.isMember(tag, root.get(Document_.tags)))
.collect(Collectors.toList());