考慮下面的註解JPA實體類「非會員」:使用JPQL查詢標準API
@Entity
@Table("foo")
public class Foo {
@Id private int id;
@Column(name="name") private String name;
@ManyToMany
@JoinTable(name = "foo_tags",
joinColumns = {@JoinColumn(name = "foo")},
inverseJoinColumns = {@JoinColumn(name = "tag")})
private Collection<Tag> tags;
...
}
@Entity
@Table(name = "tag")
public class Tag {
@Id private String tag;
...
}
我試圖制定一個查詢來獲取缺少一個給定的標籤的所有富實例。下面JPQL查詢的伎倆
SELECT f FROM Foo f WHERE :tag NOT MEMBER OF f.tags
但是,我無法轉化爲條件查詢此。翻譯似乎很明顯(對我來說):
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> query = cb.createQuery(Foo.class);
Root<Foo> from = query.from(Foo.class);
query.where(cb.isNotMember(cb.parameter(Tag.class, "tag"), from.get(Foo_.tags)));
TypedQuery<Foo> tq = em.createQuery(query);
return tq.setParameter("tag", sometag).getResultList();
雖然這些情況下生成的SQL有很大不同。第一個查詢生成以下內容:
SELECT t0.id, t0.name FROM foo t0
WHERE NOT EXISTS (
SELECT DISTINCT t2.TAG FROM tag t2, foo_tags t1
WHERE (((t1.foo = t0.id) AND (t2.TAG = t1.tag)) AND ('blue' = t2.TAG)))
而條件查詢生成此:
SELECT t1.id, t1.name FROM tag t0, foo_tags t2, Foo t1
WHERE (NOT ((t0.TAG = 'blue')) AND ((t2.foo = t1.id) AND (t0.TAG = t2.tag)))
我只測試了使用的EclipseLink實現,所以可能有問題存在,但想通我如果有人發現一個明顯的錯誤,首先在這裏問。
似乎這是一個Eclipselink問題,使用Hibernate的JPA實現(3.5.0.Final),條件查詢是正確生成的。 – 2011-05-17 10:42:14
EclipseLink 2.4 RC 2 – Gandalf 2012-06-22 14:32:04