2

I am curious as to why it is possible, with the CriteriaBuilder class of JPA 2, to create such queries. Suppose I have a User class with a persisted String called name as attribute. Why can I write this?

CriteriaBuilder builder = mgr.getCriteriaBuilder();

CriteriaQuery<User> crit = builder.createQuery(User.class);
Root<User> user = crit.from(User.class);                     // 1
crit.select(user)
    .where(builder.equal(user.get(User_.name), 2.5));        // 2

First, at Marker 1: Why must I indicate User.class again? Isn't my CriteriaQuery supposed to know I'm interested in users anyway? Doesn't it break type safety to possibly inject another class here?

Second, at Marker 2: The name property is a String. Why can I compile nonsense like this, comparing a String with a double? In other words, why is the signature of the called equal method this:

public Predicate equal(Expression<?> x, Object y)

instead of a presumably more type safe version as follows?

public <T> Predicate equal(Expression<T> x, T y)

Would other query frameworks like Querydsl provide a better solution to this issue?

Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234

2 Answers2

2

I believe the typesafe aspects of the JPA 2 Criteria API were added at a quite late point of the specification process. That's why it doesn't feel consistent.

Querydsl is more concise than the JPA 2 Criteria API and also more typesafe. Querydsl uses fluent builders instead of a factory class for predicate creation, so the equivalent method can be found here http://www.querydsl.com/static/querydsl/2.8.0/apidocs/com/mysema/query/types/expr/SimpleExpression.html#eq%28T%29

I am the maintainer of Querydsl, so this answer is biased.

Timo Westkämper
  • 21,824
  • 5
  • 78
  • 111
  • I’ve just had a closer look at Querydsl and it sure looks very, very good. I love it. The only downside is the number of dependencies. Do I really need all of them? Is there a document somewhere that says which jars are needed for which features? – Jean-Philippe Pellet Oct 20 '12 at 09:21
  • Which dependencies are you concerned about? There is no document declaring which dependency is used for which feature. – Timo Westkämper Oct 21 '12 at 12:32
  • Do I need stuff like antlr, asm, glib, ecj, guava, validation-api if I just want to have the nice JPA queries? – Jean-Philippe Pellet Oct 24 '12 at 16:41
  • The compile scope dependency set is smaller than that. You can set the querydsl-apt dependency to provided and exclude cglib and asm if you don't need the proxy features. – Timo Westkämper Oct 25 '12 at 06:31
  • OK, I’ll check that, thanks. I had just directly downloaded the archive and assumed that everything was needed. – Jean-Philippe Pellet Oct 25 '12 at 08:28
2

specific on JPA you can use also Object Query or Torpedo Query(but this is specialized on HQL) that not needs compile time model generation. anyway QueryDsl is one of the first to implement typesafe query

tglman
  • 470
  • 3
  • 8