Zgodnie ze specyfikacją JPA 2.0:
Zbudowałem jednak przykład pracy na GitHubie za pomocą hibernacji.
Zakładając, że mamy to CalendarEvent
podmiot i MailingCode
Obiekt DTO:
@Entity(name = "CalendarEvent")
@Table
public static class CalendarEvent implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ElementCollection
private final List<Integer> mailingCodes = new ArrayList<>();
}
public static class MailingCode {
private Integer id;
public MailingCode(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
Możesz napisać kod Criteria API w następujący sposób:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<CalendarEvent> criteria = builder.createQuery(CalendarEvent.class);
Root<CalendarEvent> root = criteria.from(CalendarEvent.class);
List<MailingCode> mailingCodes = Arrays.asList(
new MailingCode(1),
new MailingCode(2),
new MailingCode(3)
);
Expression<List<Integer>> mailingCodesPath = root.get("mailingCodes");
Predicate predicate = builder.conjunction();
for(MailingCode mailingCode: mailingCodes){
predicate = builder.and(predicate, builder.isMember(mailingCode.getId(), mailingCodesPath));
}
criteria.where(predicate);
List<CalendarEvent> events = entityManager.createQuery(criteria).getResultList();
Jednak zapytanie IN jest znacznie lepszym wyborem, ponieważ powyższe zapytanie SQL jest nieoptymalne.