Using Hibernate 4.1.7, I've got the following entity:
Code:
@Entity
public class EntityClass {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer value;
}
And I'm running a few queries for it as follows:
Code:
private void queryAttribute(String attribute, Object value) {
EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<EntityClass> query = cb.createQuery(EntityClass.class);
Root<EntityClass> root = query.from(EntityClass.class);
query.select(root).where(cb.equal(root.get(attribute), value));
em.createQuery(query).getResultList();
em.close();
}
...
queryAttribute("id", 1L);
queryAttribute("name", "foo");
queryAttribute("value", 50);
...
With the "hibernate.show_sql" option set to true, I see the following output:
Code:
Hibernate: select entityclas0_.id as id0_, entityclas0_.name as name0_, entityclas0_.value as value0_ from EntityClass entityclas0_ where entityclas0_.id=1
Hibernate: select entityclas0_.id as id0_, entityclas0_.name as name0_, entityclas0_.value as value0_ from EntityClass entityclas0_ where entityclas0_.name=?
Hibernate: select entityclas0_.id as id0_, entityclas0_.name as name0_, entityclas0_.value as value0_ from EntityClass entityclas0_ where entityclas0_.value=50
The question is - why aren't the conditions for the "id"/"value" fields parameterised, as it is for "name"? Running equivalent queries with with the Criteria API produces parameterized query strings.
If you wonder why I'd care - this is preventing the QueryPlanCache from recognizing similar queries, and we end up with thousands of query strings in the cache which are completely identical in structure. The plan cache seems pointless overhead in this instance, where it ought to be providing real benefit.