使用JPA规范找不到具有多对多关系的实体的实体

时间:2016-09-22 17:59:33

标签: spring hibernate spring-data spring-data-jpa hibernate-criteria

我希望将此查询实现为Spring Data存储库的规范:

select * from Parts 
 where id not in (select partId 
                    from PartsToDeliveries
                    where deliveryId = 31)

(基本上,找到不属于特定交货的所有零件)

以下是课程:

@Entity
public class Part {
    @Id
    private Long id;

    @ManyToMany
    @JoinTable(name = "PartsToDeliveries", joinColumns = {@JoinColumn(name = "partId")}, inverseJoinColumns = @JoinColumn(name = "deliveryId"))
    private Set<Delivery> deliveries = new HashSet<>();
}

@Entity
public class Delivery {

    @Id
    private Long id;

    @ManyToMany(mappedBy = "deliveries")
    private List<Part> parts;
}

填空:

Specification<Part> specification = (root, criteriaQuery, criteriaBuilder) ->     {
    ? _______ ?
}

我根本不知道从哪里开始。

3 个答案:

答案 0 :(得分:2)

Antoniossss有正确的解决方案(文档没有特别帮助)。为了完整起见,这是最终的解决方案:

specification = (root, criteriaQuery, criteriaBuilder) -> {
                Subquery<Long> subquery   = criteriaQuery.subquery(Long.class);
                Root<Part>     subFrom    = subquery.from(Part.class);
                Path<Long>     deliveryId = subFrom.join("deliveries").get("id");
                subquery.select(subFrom.get("id"));
                subquery.where(criteriaBuilder.equal(deliveryId, 31l));

                Path<Long> id = root.get("id");
                return criteriaBuilder.not(criteriaBuilder.in(id).value(subquery));
            };

答案 1 :(得分:0)

您可以使用CriteriaAPI - CriteriaBuilder#not()subquery()

来模拟类似的语义

这里有你构建类似查询的例子 JPA 2.0, Criteria API, Subqueries, In Expressions

以下是JPA文档http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/CriteriaBuilder.html

答案 2 :(得分:0)

类似的东西:

criteriaBuilder.not(root.get("deliveries").in(notWantedDelivery))