Search code examples
spring-data-jpacriteria

JPA Specification: Select all entities which have at least one param with attribute from list


I have 2 entities with relationship ManyToMany

@Entity
@Table
public class TranslationUnit implements Serializable {

@Id
private Long id;


@ManyToMany(mappedBy = "translationUnit", fetch = FetchType.EAGER)
    private Set<Category> categories = new HashSet<>();
}

@Entity
@Table
public class Category implements Serializable {
@ManyToMany
    @JoinTable(name = "category_translation_unit",
               joinColumns = @JoinColumn(name = "categories_id", referencedColumnName = "id"),
               inverseJoinColumns = @JoinColumn(name = "translation_units_id", referencedColumnName = "id"))
    private Set<TranslationUnit> translationUnits = new HashSet<>();
}

In Category I have 1 field, which should be used for filtering:

String name;

I need to be able to specify list of Category names (List), and select those TranslationUnits which have at least one Category with specified name. I have several other filtering options, which should be used together, and I successfully built Specifications for them. But I've stuck with this one.

Please help.

P.S. One of my existing Specifications looks like this:

Specification idSpec = (Specification) (r, q, cb) -> {

            List<Predicate> predicates = new ArrayList<>();

            if (!filterRequest.getTranslationUnitIds().isEmpty())
                predicates.add(r.get(TranslationUnit_.id).in(filterRequest.getTranslationUnitIds()));

            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

Solution

  • Good day. You could use IN for filtering translation units by category names list. I believe, it will look like this using Criteria API:

    Root<TranslationUnit> itemsRoot = ...;
    Join join = itemsRoot.join("categories");
    List<Predicate> predicates = new ArrayList<>();
    predicates(join.get("name").in(categoryNamesList));