2

I'm looking to implement this query as a Specification for a Spring Data repository:

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

(Basically, find all the parts that were not part of a certain delivery)

Here are the classes:

@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<>();
}

and

@Entity
public class Delivery {

    @Id
    private Long id;

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

Fill in the blank:

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

I simply don't know where to start on this.

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
Steve s.
  • 301
  • 1
  • 4
  • 13

3 Answers3

2

Antoniossss had the right lead to the solution (the doc not being particularly helpful). For completeness here is the final solution:

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));
            };
Steve s.
  • 301
  • 1
  • 4
  • 13
0

You can mock the similar semantics using CriteriaAPI - CriteriaBuilder#not() and subquery()

Here u have SO example of building similar query JPA 2.0, Criteria API, Subqueries, In Expressions

and here are JPA docs http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/CriteriaBuilder.html

Community
  • 1
  • 1
Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

Something like:

criteriaBuilder.not(root.get("deliveries").in(notWantedDelivery))
Ralph
  • 118,862
  • 56
  • 287
  • 383
  • Thanks Ralph, but that created a SQL error. like: `and deliveries1_deliveryId=part2_.id and 1=1 and (. not in (47))`. – Steve s. Sep 22 '16 at 22:12