Java 如何使用HQL通过所述PK的列表过滤具有复合PK的实体?

Java 如何使用HQL通过所述PK的列表过滤具有复合PK的实体?,java,hibernate,jpa,hql,Java,Hibernate,Jpa,Hql,考虑: @Entity public class Foo { @EmbeddedId private FooPK pk; public FooPK getPk() { return pk; } public void setPk(FooPK pk) { this.pk = pk; } } 及 我有一个在HQL中尝试用作筛选器的列表: -这只是我想做的一个例子。 从foo-foo中选择foo foo.pk在何处:pkList 这不起作用,因为pk不是单个值。我只

考虑:

@Entity
public class Foo {
    @EmbeddedId
    private FooPK pk;

    public FooPK getPk() { return pk; }
    public void setPk(FooPK pk) { this.pk = pk; }
}

我有一个在HQL中尝试用作筛选器的列表:

-这只是我想做的一个例子。 从foo-foo中选择foo foo.pk在何处:pkList 这不起作用,因为pk不是单个值。我只是想列出我拥有pks的所有实体

我可以打破列表,做如下操作:

-丑陋的 从foo-foo中选择foo 哪里 foo.pk.idA=:idA1和foo.pk.idB=:idB1 或者foo.pk.idA=:idA2和foo.pk.idB=:idB2 或者foo.pk.idA=:idA3和foo.pk.idB=:idB3 - ... 但我相信你可以看到这是多么丑陋和不可缩放

我正在使用Java6/JPA1/Hibernate3

无论如何,我使用的是Oracle,我希望生成的SQL类似于:

-假设模式包含引用的表和列,这在我的数据库中可以正常工作。 选择foo.ID\u A、foo.ID\u B 来自富福 其中foo.ID_A,foo.ID_B在? 您可以使用API替换hql


以下内容适用于MySQL:

为@Entity创建javax.persistence.NamedQuery

选择通过

final TypedQuery<Foo> typedQuery = this.entityManager.createNamedQuery("select", Foo.class);
final FooPK fooPk = new FooPK(...); // Create example FooPK
typedQuery.setParameter("pks", Arrays.asList(fooPk, fooPk));

return typedQuery.getResultList();

注意每个idA和idB的两个检查

回答正确。不幸的是,我几乎可以肯定我只限于hql,我将不得不再次检查这一点,很难。很抱歉没有在我的问题中说明这一点。我最后做了一个变通办法。因为这是在我的环境中实际可行的唯一答案——尽管不是hql——我接受它。谢谢。您是否按照我在回答中的建议,尝试在命名参数周围不加括号?您使用的是哪些RDBMS,例如MySQL、Oracle等?@SteveChambers我使用的是Oracle检查我的编辑。另外,不幸的是,我对数据库没有控制权。无论如何,我使用的是Oracle,我希望生成的SQL类似于。。。。那么生成的SQL是什么样子的呢?当然,这不起作用,因为pk不是一个单一的值。你怎么知道的?有没有明确提到不支持这种做法?还有,你说的“不工作”是什么意思?返回错误的结果?抛出错误?@AlanHay如果我尝试这样使用查询,Hibernate会抛出QueryException。没有生成SQL。如果你再看一遍这个问题,你会发现这个HQL只是我试图做的一个例子,而不是一个实际的实现。关于你的第二个问题:我不知道。也许那当然给了你错误的印象。我把它删掉了。
// your list of FooPks
List<FooPk> pkList = ....

//Create a criteria over an entity
Criteria  criteria = session.createCriteria(Foo.class);
// add a restriction
criteria.add(Restrictions.in("pk", pkList));
// Execute query and get result.
List<Foo> foos = criteria.list();
@NamedQuery(name = "select", query = "SELECT foo FROM Foo foo WHERE foo.pk IN :pks")
final TypedQuery<Foo> typedQuery = this.entityManager.createNamedQuery("select", Foo.class);
final FooPK fooPk = new FooPK(...); // Create example FooPK
typedQuery.setParameter("pks", Arrays.asList(fooPk, fooPk));

return typedQuery.getResultList();
select ... from ... where foo0_.idA=? and foo0_.idB=? or foo0_.idA=? and foo0_.idB=?