У меня есть две сущности в отношениях @ManyToMany
.
// 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;
Таблица соединений называется output_has_interval
между output
и interval
.
Как мне сделать CriteriaQuery
как это?
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'
Это работает, как и ожидалось, если я выпущу его в MySQL.
(У меня также есть соответствующие классы статической метамодели, по запросу я могу их опубликовать - ничего особенного.)
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);
Однако tq.getResultList
возвращает каждую строку output
из моей базы данных. Есть идеи?
(С другой стороны: Hibernate (поставщик, которого я использую) генерирует много select
операторов, когда я выполняю этот запрос, по одному на каждое отношение, Output
имеет, иногда больше.)
Ред .: Я написал:
tq.getResultList
возвращает каждый
output
строка из моей базы данных
Для пояснения: он возвращает больше, чем просто каждую строку output
из моей базы данных. На самом деле соединение выполняется с использованием output
и interval
, однако предикат:
`interval`.`start` >= '2011-04-30'
не устраивает.