The JPA provides three basic types of queries
- Query written in JPQL. It has subtypes of TypedQuery and NamedQuery.
- NativeQuery written in plain SQL.
- 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"))