Last Updated on 04 August 2019   |   Print Email
This tutorial guides you how to use named queries in Java Persistence API (JPA). Basically you execute a query in JPA like this:
String jpql = "SELECT u from User u";
Query query = entityManager.createQuery(jpql);
List<User> result = query.getResultList();
for (User user : result) {
System.out.println(user);
}
This approach is perfect for simple applications that have only a small number of queries. What if your application becomes larger with tens or hundreds queries scattered in many classes? Then imagine the nightmare of maintaining such a large number of queries in your fat code base. Therefore, JPA provides the concept of named queries to make programmer’s life easier: you can group related queries in one place (usually in model classes) and refer them in your code by their names - hence the term named queries. Below is an example:
Here, the query name “User.findAll” refers to a query which can be stored in a relevant domain model class like this:
@Entity
@Table(name = "USERS")
@NamedQueries({
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u ORDER BY u.fullname")
})
public class User {
private Integer id;
private String fullname;
private String email;
private String password;
...
...
}
As you can see, there are two annotations are used for named query:@NamedQueries annotation consists of a set of @NameQuery annotations with each define a specific JPQL query:
@NamedQueries({
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u ORDER BY u.fullname")
})
To specify multiple named queries, separate the @NameQuery annotations by commas:
@NamedQueries({
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u ORDER BY u.fullname"),
@NamedQuery(name = "User.count", query = "SELECT COUNT(*) FROM User u"),
@NamedQuery(name = "User.removeAll", query = "DELETE FROM User u")
})
The following code illustrates how to execute the named query User.count above:
Query query = entityManager.createNamedQuery("User.count");
long count = (long) query.getSingleResult();
And the following example executes the named query User.removeAll above:
If your query consists of parameters, you can use the setParameter(name, value) or setParameter(position, value) to set values for the parameters dynamically.For example, consider the following named query that contains one parameter named email:
@NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email")
The following code sets parameter for this query and executes it (set values for parameters by their names):
String queryName = "User.findByEmail";
String email = "tom@gmail.com";
Query query = entityManager.createNamedQuery(queryName);
query.setParameter("email", email);
User user = (User) query.getSingleResult();
And this named query has two positional parameters:
@NamedQuery(name = "User.checkLogin", query = "SELECT u FROM User u WHERE u.email = ?1 AND password = ?2")
And the following code sets values for the positional parameters above:
It’s recommended to use name-based parameters for the readability of your code.
Named Queries Stored in XML:
Besides embedding named queries in model classes, you can also store named queries in a separate XML file. For example, create queries.xml file under META-INFdirectory with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="2.0" xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_2_0.xsd "
>
<named-query name="WhoUsingGmail">
<query>SELECT u FROM User u WHERE u.email LIKE '%gmail%'</query>
</named-query>
<named-query name="WhoNotSetPassword">
<query>SELECT u FROM User u WHERE u.password is null</query>
</named-query>
</entity-mappings>
And tell JPA to load this XML file in the persistence.xml file like this:
Then you can use named queries in your code normally. This configuration is more flexible as we don’t have to re-compile the code when making changes to the queries.
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.
Hi Nam, Hope you are doing well. Can you please give me a query for below scenario. a.Add a “Named Query” called ‘findByCdPrice’ which should show all the CDs which have a price greater than the given price. b.The above query should also show the ‘No. of CDs’ as per the price criteria
Comments
Can you please give me a query for below scenario.
a.Add a “Named Query” called ‘findByCdPrice’ which should show all the CDs which have a price greater than the given price.
b.The above query should also show the ‘No. of CDs’ as per the price criteria