There are two methods of querying entities using the Java Persistence API. The Java Persistence query language (JPQL) is a simple, string-based language similar to SQL used to query entities and their relationships. See Chapter 21, The Java Persistence Query Language for more information on the Java Persistence query language. The Criteria API is used to create type-safe queries using Java programming language APIs to query for entities and their relationships. See Chapter 22, Creating Queries Using the Criteria API for more information on the Criteria API.
Each approach, JPQL and the Criteria API, has advantages and disadvantages.
JPQL queries are typically more concise compared to Criteria queries, just a few lines long. They also tend to be more readable compared to Criteria queries, and developers familiar with SQL will find it easy to learn the syntax of JPQL. JPQL named queries can be defined in the entity class using a Java programming language annotation, or in the application's deployment descriptor. JPQL queries are not type-safe, however, and require a cast when retrieving the query result from the entity manager. This means that type casting errors may not be caught at compile-time. JPQL queries don't support open-ended parameters.
Criteria queries allow you to define the query in the business tier of the application. While this is also possible using JPQL dynamic queries, Criteria queries provide better performance because JPQL dynamic queries must be parsed each time they are called. Criteria queries are type-safe, and therefore don't require casting like JPQL queries. The Criteria API is just another Java programming language API, and doesn't require developers to learn the syntax of another query language. Criteria queries are typically more verbose compared to JPQL queries, and require the developer to create several objects and perform operations on those objects before submitting the query to the entity manager.