Если вы пытаетесь применить множественные спецификации к разным объектам для получения результата, вы не сможете смешивать разные типы спецификаций, поскольку спецификации привязаны к объектам, которые вы пытаетесь получить из вашего запроса. Однако вы можете достичь такого результата, объединяя спецификации для сущности, которую вы пытаетесь получить, используя соединения.
Допустим, у вас есть сущность Product, которая содержит сущности Field с атрибутом «name», которые сами содержатОбъекты FieldValue с атрибутами «значение». Вы хотите получить продукт по имени поля, имеющему одно или несколько значений FieldValues. Вот фрагмент кода, который даст вам желаемый результат:
Specification<Product> fieldNameHavingValues(String fieldName, List<String> fieldValues) {
return ((root, criteriaQuery, criteriaBuilder) -> {
if (fieldName == null || fieldValues == null || fieldValues.isEmpty()) {
return null;
}
Join<Product, Field> fieldJoin = root.join(Product_.fields); // First join on Field table
Predicate namePredicate = criteriaBuilder.equal(fieldJoin.get(Field_.name), fieldName); // Assert that the field name has the desired one
Join<Field, FieldValue> valueJoin = fieldJoin.join(Field_.fieldValues); // Join the third table, i.e. the FieldValue table
Expression<String> expression = valueJoin.get(FieldValue_.value);
Predicate valuePredicate = expression.in(fieldValues); // Assert that the values are in the given collection
return criteriaBuilder.and(namePredicate, valuePredicate); // Return the combined predicate
});
}
List<Product> prods = productRepository.findAll(fieldNameHavingValues("colors", Arrays.asList("blue", "orange")));
Этот конкретный пример будет получать список всех продуктов, имеющих поле с именем "colors", содержащее либо значение "blue", либо "orange".
Обратите внимание, что вам придется расширять свой репозиторий JpaSpecificationExecutor:
public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product>
и генерировать метамодели, например, используя Maven:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.3.7.Final</version>
<scope>provided</scope>
</dependency>
Надеюсь, это поможет