jpa 如何使用Specifications查询@ElementCollection

epfja78i  于 2023-06-30  发布在  其他
关注(0)|答案(2)|浏览(217)

我有一个包含不同字段的实体,包括一个@ElementCollections列表:

@Entity
public class Property {

//different attributes

@ElementCollection
@Enumerated(EnumType.STRING)
protected List<PropertyCriteria> criterias = new ArrayList<>();

}

其中PropertyCriteria是一个简单的枚举类。
我想实现一个搜索方法,接收多个值,并返回相应的清单。

@GetMapping(value = "/search")
public Page<Property> search(
  @RequestParam Map<String, String> filters,
  @RequestParam(value = "criterias") List<PropertyCriteria> criterias, 
  Pageable pageable) {
return service.search(filters, criterias, pageable);

}
为了做到这一点,在我看来,规范是最好的方法,因为我将有其他属性进行过滤。criterias参数是一个列表,其中包含属性(ElementCollections)中所需的所有值。过滤器Map是一个键值参数,包含我收到的所有其他属性。我试过这样的东西,但它不工作:

public Page<Property> search(Map<String, String> filters, List<PropertyCriteria> criterias,
  Pageable pageable) {
  Specification<Property> specification = Specification
  .where(criteriasFilter(criterias)
  //.and(others specifications on other attributes)
  ;
  return repository.findAll(specification, pageable);
}
public static Specification<Property> criteriasFilter(List<PropertyCriteria> criterias) {
    Specification<Property> propertySpecification = (root, query, builder) -> {
      query.distinct(true);
      Predicate where = builder.conjunction();
      return builder.and(where, root.joinList(Property_.CRITERIAS).in(
          criterias));
    };
    return propertySpecification;
  }

希望你们能帮助我:)非常感谢:)
您好

km0tfn4u

km0tfn4u1#

如果需要所有条件都匹配,最好创建一个带有计数的子查询,并检查计数是否是预期的。就像这样:

public static Specification<Property> criteriasFilter(List<PropertyCriteria> criterias) {
    Specification<Property> propertySpecification = (root, query, builder) -> {
      Subquery<Long> subquery = query.subquery(Long.class);
      Root<Property> r = subquery.correlate(root);
      subquery.where(r.joinList(Property_.CRITERIAS).in(
          criterias));
      subquery.select(builder.count(builder.literal(1)));
      return builder.equal(subquery, (Long) criterias.size());
    };
    return propertySpecification;
}
8fq7wneg

8fq7wneg2#

在我的例子中,这个代码起作用了

Specification<Preparazione> newSpec = (root, query, qb) -> {
            return qb.isMember(idIndicazione, root.get("indicazioniTer"));
        };

我的实体是这样的

@Entity
    public class Preparazione {
        @Id
        public Long idPreparazione;
        
        @ElementCollection(targetClass = Long.class)
        @Column(name = "id_indicazione")
        @CollectionTable(
                name = "preparazioni_indicazione",
                joinColumns = @JoinColumn(name = "id_preparazione")
        )
        public List<Long> indicazioniTer = new ArrayList<>();
    }

idIndicazione是包含要搜索的值的变量

相关问题