Java jpa:查找具有多对多属性的实体,该属性包含给定集合的每个元素
我有两个实体:Post和AttributesJava jpa:查找具有多对多属性的实体,该属性包含给定集合的每个元素,java,jpa,Java,Jpa,我有两个实体:Post和Attributes public class DbPost { .... @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinTable(name = "posts_attributes", joinColumns = {@JoinColumn(name = "post_id")},
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;
...
}
公共类DbPost{
....
@ManyToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinTable(name=“posts\u attributes”,
joinColumns={@JoinColumn(name=“post_id”)},
inverseJoinColumns={@JoinColumn(name=“attribute\u value\u id”)}
@Builder.Default
private Set attributeValues=new HashSet();
....
}
公共类DbAttributeValue{
...
@身份证
@列(name=“attribute\u value\u id”)
@GeneratedValue(策略=GenerationType.IDENTITY)
@属性定义
私人长id;
...
}
现在,我如何从AttributeValue ID列表中获取所有帖子,其中每个帖子都包含每个AttributeValue
我已经试过了:
List<DbPost> findAllByAttributeValuesIdIn(Collection<Long> attributeValues_Id);
列出findAllByAttributeValuesIdIn(集合属性值\u Id);
及
公共规范createPostJpaSpecification(列出AttributeValueId){
返回(根、查询、准则生成器)->{
列表谓词=新的ArrayList();
if(attributeValueIds!=null&&attributeValueIds.size()>0){
谓词.add(
root.joinSet(“attributeValues”).get(“id”).in(attributeValueIds)
);
}
返回criteriaBuilder.and(谓词.toArray(新谓词[0]);
};
}
我做错了什么?试试这个
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);
}
公共规范createPostJpaSpecification(列出AttributeValueId){
返回(根、查询、生成器)->{
最终列表谓词=new ArrayList();
if(attributeValueIds!=null){
for(长id:AttributeValueID){
谓词.add(
createAttributeIdPredicate(id、根、查询、生成器)
);
}
}
返回criteriaBuilder.and(predicates.toArray(新谓词[predicates.size()]);
};
}
谓词CreateAttributeId谓词(长attributeId、根、CriteriaQuery查询、CriteriaBuilder){
Subquery Subquery=query.Subquery(Integer.class);
Root post=subquery.from(DbPost.class);
Join属性=post.Join(“attributevalue”);
谓词mainQueryRelationPredicate=builder.equal(root.get(“id”)、post.get(“id”);
谓词子querypredicate=builder.equal(attribute.get(“id”),attributeId);
subquery.select(builder.literal(1))
.where(mainQueryRelationPredicate,subqueryPredicate);
返回builder.exists(子查询);
}
编号。DbAttributeValue实体中的id是唯一的。这是该实体的主键可以帮助->祝你好运!谢谢我已经使用本机查询解决了我的问题,但您的解决方案也很有效!
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);
}