2011-05-17 63 views
1

考慮下面的註解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實現,所以可能有問題存在,但想通我如果有人發現一個明顯的錯誤,首先在這裏問。

+0

似乎這是一個Eclipselink問題,使用Hibernate的JPA實現(3.5.0.Final),條件查詢是正確生成的。 – 2011-05-17 10:42:14

+0

EclipseLink 2.4 RC 2 – Gandalf 2012-06-22 14:32:04

回答

0

SQL應該是相同的,儘管兩者似乎都是可行的(減去空白的情況)。

請在EclipseLink中記錄標準問題的錯誤。

您應該可以使用連接或子選擇而不是語法的特殊成員。

SELECT f FROM Foo f left join f.tags t WHERE not(t == :tag) 
+0

中存在此問題遺憾的是,如果Foo具有與其關聯的多個標記,則第二個SQL不起作用。我只是遇到與EclipseLink相同的問題http://stackoverflow.com/questions/11088064/querydsl-duplicate-identification-variable-equality-syntax-error-with-any-on-set:D – Gandalf 2012-06-19 16:05:19