如何对多个实体使用单个jpa规范

时间:2019-10-22 15:04:48

标签: spring-data-jpa

我需要在不同的实体和多列上写一些标准。目前,我有多个规范类,一个针对ekach实体。如何使所有实体通用的单个jpa规范。

1 个答案:

答案 0 :(得分:0)

如果您试图将多个规范应用于不同的实体以获得结果,则您将无法混合使用不同的规范类型,因为规范与您尝试从查询中检索的实体相关。 但是,可以通过使用联接为要检索的实体链接规范来实现这种结果。

比方说,您有一个实体产品,其中包含具有“名称”属性的Field实体,它们本身也包含具有“值”属性的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")));

此特定示例将检索所有包含名为“颜色”的字段(包含“蓝色”或“橙色”值)的所有产品的列表。

请注意,您将必须使存储库扩展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> 

希望这会有所帮助