javajpa:查找具有多对多属性的实体,这些实体包含给定集合的每个元素

jv4diomz  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(267)

我有两个实体:post和attributes

public class DbPost {
    ....

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "posts_attributes",
            joinColumns = {@JoinColumn(name = "post_id")},
            inverseJoinColumns = {@JoinColumn(name = "attribute_value_id")})
    @Builder.Default
    private Set<DbAttributeValue> attributeValues = new HashSet<>();

    ....
}

public class DbAttributeValue {
    ...

    @Id
    @Column(name = "attribute_value_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @PropertyDefinition
    private Long id;

    ...
}

现在,如何从attributevalue id列表中获取所有包含attributevalue的帖子?
我已经试过了:

List<DbPost> findAllByAttributeValuesIdIn(Collection<Long> attributeValues_Id);

public Specification<DbPost> createPostJpaSpecification(List<Long> attributeValueIds) {
    return (root, query, criteriaBuilder) -> {
        List<Predicate> predicates = new ArrayList<>();
        if (attributeValueIds != null && attributeValueIds.size() > 0) {
            predicates.add(
                    root.joinSet("attributeValues").get("id").in(attributeValueIds)
            );
        }
        return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
    };
}

我做错什么了?

p4tfgftt

p4tfgftt1#

试试这个

public Specification<DbPost> createPostJpaSpecification(List<Long> attributeValueIds) {
        return (root, query, builder) -> {
            final List<Predicate> predicates = new ArrayList<>();
            if (attributeValueIds != null) {
                for(Long id : attributeValueIds) {
                    predicates.add(
                        createAttributeIdPredicate(id, root, query, builder)
                    );
                }
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
    }

    Predicate createAttributeIdPredicate(Long attributeId, Root<DbPost> root, CriteriaQuery<DbPost> query, CriteriaBuilder builder) {
         Subquery<Integer> subquery = query.subquery(Integer.class);
         Root<DbPost> post = subquery.from(DbPost.class);
         Join<DbAttributeValue, DbPost> attribute = post.join("attributeValues");

         Predicate mainQueryRelationPredicate = builder.equal(root.get("id"), post.get("id"));
         Predicate subqueryPredicate = builder.equal(attribute.get("id"), attributeId);

         subquery.select(builder.literal(1))
                 .where(mainQueryRelationPredicate, subqueryPredicate);

         return buider.exists(subquery);
    }

相关问题