I have two entities in a @ManyToMany
relationship.
// Output has 4 other @ManyToOne relationships if that matters @Entity @Table public class Output { @Id public String address; @ManyToMany(targetEntity = Interval.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinTable(name = "output_has_interval", joinColumns = {@JoinColumn(name = "output_address", referencedColumnName = "address")}, inverseJoinColumns = {@JoinColumn(name = "interval_start", referencedColumnName = "start"), @JoinColumn(name = "interval_end", referencedColumnName = "end")}) Collection<Interval> intervals; @IdClass(IntervalPK.class) // I'll omit this one. @Entity @Table public class Interval { @Id public Calendar start; @Id public Calendar start; @ManyToMany(targetEntity = Output.class, mappedBy = "intervals", cascade = CascadeType.ALL, fetch = FetchType.LAZY) public Collection<Output> outputs;
The join table is called output_has_interval
between output
and interval
.
How do I do CriteriaQuery
like this?
SELECT `output`.`address` FROM `output`, `output_has_interval`, `interval` WHERE `output`.`address` = `output_has_interval`.`output_address` AND `interval`.`start` = `output_has_interval`.`interval_start` AND `interval`.`end` = `output_has_interval`.`interval_end` AND `interval`.`start` >= '2011-04-30'
This works as expected if I issue it in MySQL.
(I have the corresponding static meta model classes as well, on request I'll could post them - nothing fancy tho'.)
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Output> cq = cb.createQuery(Output.class); Root<Output> root= cq.from(Output.class); CollectionJoin<Output, Interval> join = root.join(Output_.intervals); Expression<Calendar> start = join.get(Interval_.start); Predicate pred = cb.greaterThanOrEqualTo(start, /* calendar for '2011-04-30' */); cq.where(pred); TypedQuery<Output> tq = em.createQuery(cq);
However tq.getResultList
returns every output
row from my database. Any idea?
(On a side note: Hibernate (the provider I'm using) generates many select
statements when I issue this query, one for every relationship Output
has, sometimes more.)
Edit.: I wrote:
tq.getResultList
returns everyoutput
row from my database
To clarify it: it returns more than just every output
row from my database. It actually does a join using output
and interval
however the predicate:
`interval`.`start` >= '2011-04-30'
doesn't get satisfied.