Q:

JPA query a collection using between clause

My entity has a collection of another entity on which I need to do a BETWEEN criteria. 
I do not want to use the native query. 
I am trying to achieve this using the criteria API. 
Below is a short snippet of my entity. 
@Entity
@Table(name = "ref_dates")
public class Dates{
    @Id
    @Column(name = "ID")
    private int id;

    @OneToMany(fetch = FetchType. EAGER)
    @JoinTable(
    name="ref_dates_prg",
    joinColumns = @JoinColumn( name="DATE_PRG_ID"),
    inverseJoinColumns = @JoinColumn( name="DATE_ID")
 )    
 private Set<DateInfo> dates;

}
It has several other properties, geter/setters, etc which I have not mentioned here. 
I need to do a query on this Set for the id's in DateInfo object using between clause. 
I tried using Expression<Set<DateInfo>> but haven't reached anywhere. 
Thanks for all the help. 
Here is my criteria build up. 
final CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();

final CriteriaQuery<NetPrgTimePeriod> criteriaQuery = criteriaBuilder.createQuery(Dates.class);

List<Predicate> criteriaList = new ArrayList<Predicate>();

final Root<Dates> root = criteriaQuery.from(Dates.class);

Join<Dates, DateInfo> dateJoin = root.join("dates", JoinType. LEFT);

Predicate runDatesRange = criteriaBuilder.between(
        dateJoin.<Integer> get("id"), startDate.getId(), endDate.getId());

criteriaList.add(runDatesRange);

Join<Dates, TimeInfo> timeJoin = root.join("times", JoinType. LEFT);

Predicate timeBlocksRange = criteriaBuilder.between(
        timeJoin.<Integer> get("id"), startTime.getId(), endTime.getId());

criteriaList.add(timeBlocksRange);

criteriaQuery.where(criteriaBuilder.and(criteriaList.toArray(new Predicate[0])));

TypedQuery<NetPrgTimePeriod> query = em.createQuery(criteriaQuery);

List<Dates> results = query.getResultList();

A:

Assuming you actually mapped your collection correctly, the main part you seem to be missing is the Join:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Dates> query = cb.createQuery(Dates.class);

Root<Dates> root = query.from(Dates.class);
Join<Dates, DateInfo> infos = root.join("dates", JoinType. LEFT);

query.distinct(true);
em.createQuery(query.where(cb.between(infos.<Integer>get("id"), 1, 10))).getResultList();

Of course you can substitute metamodel fields where I used strings (which will also obsolete the need for this ugly <Integer> selector - assuming your id is an integer).