I am a bit confused about these three concepts.
From what I have read, One of the major benifits of using QueryDsl or JPA metamodel is type safety.
But I can achieve type safety even with Criteria API's. (I am using JPA with eclipselink)
javax.persistence.EntityManager
has two variants
public Query createQuery(String sqlString);
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery);
I agree with first version where I pass sql as string I don't get type safety. But with the second version I get type safety. Or am I missing something here? Can someone explain with an example how using criteria is not type safe.
What is the difference between QueryDsl and JPA static meta model ?
JPA (Java persistence API) metamodel classes are classes that describe the structure of JPA entity classes (classes used to store database state as Java objects). They enable you to write Java code for creating database queries in a typesafe way.
Querydsl is an extensive Java framework, which allows for the generation of type-safe queries in a syntax similar to SQL. It currently has a wide range of support for various backends through the use of separate modules including JPA, JDO, SQL, Java collections, RDF, Lucene, Hibernate Search, and MongoDB.
EntityManager instance is used to create a CriteriaBuilder object. CriteriaQuery instance is used to create a query object. This query object's attributes will be modified with the details of the query. CriteriaQuery. from method is called to set the query root.
Hibernate Static Metamodel Generator is an annotation processor based on JSR_269 with the task of creating JPA 2 static metamodel classes. The following example shows two JPA 2 entities Order and Item , together with the metamodel class Order_ and a typesafe query.
The JPA provides three basic types of queries
Each of these methods has it's own pros/cons, so you will choose one depending on your nees.
QueryDSL is a library that is more simple and intuitive(IMHO) alternative to JPA's Criteria API.
Example used in question is TypedQuery. It is just subtype of Query which defines return type when it's known beforehand, and removes possible type cast exception. It's only about return type, the query itself is still build with plain JPQL string so it's not type safe query. On the other hand Criteria API is type-safe. We build query programmatically and we know the types of Entity's properties.
Example for classic Employee entity with department relation.
Criteria Api can be used with string based attributes. You can mistype "dept" and you get error.
Root<Employee> employee = query.from(Employee.class);
query.select(employee).where(cb.equal(employee.get("dept"), "HR"));
Or we can reference attributes using metamodel class generated by Jpa metamodel. You can't mistype dept as you can only use existing property names from Employee.
Root<Employee> employee = query.from(Employee.class);
query.select(employee).where(cb.equal(employee.get(Employee_.dept), "HR"));
Or we can use QueryDSL:
QEmployee employee = QEmployee.employee;
query.from(employee).where(employee.dept.eq("HR"))
You can use JPA meta model in Criteria API for type safety, but criteria api is quite complicated comparing to QueryDSL
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With