Consider:
@Entity
public class Foo {
@EmbeddedId
private FooPK pk;
public FooPK getPk() { return pk; }
public void setPk(FooPK pk) { this.pk = pk; }
}
and
@Embeddable
public class FooPK {
@Column(name="ID_A")
private Long idA;
@Column(name="ID_B")
private Long idB;
public Long getIdA() { return idA; }
public void setIdA(Long idA) { this.idA = idA; }
public Long getIdB() { return idB; }
public void setIdB(Long idB) { this.idB = idB; }
}
I have a List<FooPK>
that I'm trying to use as a filter in HQL:
-- Just an example of what I'm trying to do.
SELECT foo FROM Foo foo
WHERE foo.pk IN (:pkList)
This doesn't work, because pk
is not a single value. I'm simply trying to list all of the entities that I have the pks from.
I can break the list and do something like this:
-- Ugly
SELECT foo FROM Foo foo
WHERE (
(foo.pk.idA = :idA1 AND foo.pk.idB = :idB1)
OR (foo.pk.idA = :idA2 AND foo.pk.idB = :idB2)
OR (foo.pk.idA = :idA3 AND foo.pk.idB = :idB3)
-- ...
)
But I'm sure you can see how ugly and unscalable this is.
I'm using Java 6/JPA 1/Hibernate 3
For what it's worth, I'm using Oracle, and I'm expecting the SQL generated to be something like:
-- This works fine in my database, assuming the schema contains the refered table and columns.
SELECT foo.ID_A, foo.ID_B
FROM Foo foo
WHERE (foo.ID_A, foo.ID_B) in ((?,?), (?,?), (?, ?))
Your can use the Criteria API to replace your 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();
The following worked for MySQL:
Create a javax.persistence.NamedQuery
for the @Entity
@NamedQuery(name = "select", query = "SELECT foo FROM Foo foo WHERE foo.pk IN :pks")
Select via
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();
The resulting SQL:
select ... from ... where foo0_.idA=? and foo0_.idB=? or foo0_.idA=? and foo0_.idB=?
(Note the two checks for each idA
and idB
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.