给出以下JPA带注释的实体类:
@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;
...
}
我正在尝试制定查询以获取缺少给定标记的所有Foo实例。以下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 :(得分:0)
SQL应该是相同的,虽然它们看起来都可以工作(减去空的情况)。
请在EclipseLink中记录标准问题的错误。
您应该能够使用连接或子选择而不是语法的特殊成员。
SELECT f FROM Foo f left join f.tags t WHERE not(t == :tag)