I seem to have missed something in JPA's criteria API and its type safety. Consider the following code:
@Entity
@Access(FIELD)
class User(
@Id
Long id;
@Column(unique=true)
String email;
String password;
}
Here the meta model:
@StaticMetamodel(User.class)
public static class User_ {
public static volatile SingularAttribute<User, Long> id;
public static volatile SingularAttribute<User, String> email;
public static volatile SingularAttribute<User, String> password;
}
Then some code to exercise the class, built using pages from the Java EE Tutorial:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> user = cq.from(User.class);
cq.select(user);
cq.where(cb.equal(user.get(User_.email), "john@google.com")); //this line is my problem
TypedQuery<User> q = em.createQuery(cq);
List<User> allUsers = q.getResultList();
assertEquals(1, allUsers.size());
It works fine. However, if I change the "where" clause to use an Integer instead of a String ("john@google.com"), I expected the code to not compile. Yet it compiles fine.
I thought the criteria API was supposed to be type safe? That is hardly more type safe than the following, using standard JPQL. I mean, what is the purpose of the meta model in the above code?? I have gained nothing from it.
User u = em.createQuery("select u from User u where u.email = :email", User.class)
.setParameter("email", "john@google.com")
.getSingleResult();
So the question is: can I make the criteria API query more type safe, so that I can only pass a String to the "from" clause?