Criteria Api Vs QueryDsl Vs JPA metamodel
Asked Answered
D

2

18

I am a bit confused about these three concepts.

  • Criteria API
  • Query Dsl
  • Jpa 2.0 meta model

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 ?

Disputatious answered 15/11, 2018 at 18:8 Comment(1)
You are right about the type safe Criteria queries, more info here: developer.ibm.com/articles/j-typesafejpaCrunode
M
18

The JPA provides three basic types of queries

  1. Query written in JPQL. It has subtypes of TypedQuery and NamedQuery.
  2. NativeQuery written in plain SQL.
  3. Criteria API query constructed programmatically. It can use Jpa metamodel to specify attribute to make it more safe.

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"))
Mcqueen answered 6/11, 2019 at 15:6 Comment(0)
U
7

You can use JPA meta model in Criteria API for type safety, but criteria api is quite complicated comparing to QueryDSL

Unifoliate answered 16/11, 2018 at 13:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.