NamedQuery is another useful feature provided by hibernate. Sometimes, we require a query or a bunch of queries multiple times in the life of an application; at such a time, this feature helps.
Let's create a scenario to understand this feature.
Let's consider that we want to search a category by name. The following code shows how NamedQuery would help us in this case.
For this, we will use the @NamedQuery
and @NamedQueries
annotations in a class:
@NamedQuery
: This annotation is used to define a single named query@NamedQueries
: This annotation is used to define multiple queriesUpdate the following code in their respective files:
Source file: Category.java
@NamedQuery(name="getCategoryNameByName", query="FROM Category c WHERE c.name=:name") @Entity @Table(name = "category") public class Category { // fields and getters/setters }
Here, we defined NamedQuery using the @NamedQuery
annotation, and we used two attributes.
The name
attribute accepts string, which helps to identify NamedQuery. For example: name="getCategoryNameByName"
.
The query
attribute accepts string. This defines a query, which can be either SQL or HQL. For example: query="FROM Category c WHERE c.name=:name"
.
Take a look at the following code:
/* Line 1 */ Query query = session.getNamedQuery("getCategoryNameByName"); /* Line 2 */ query.setString("name", "Stationary"); List list = query.list(); System.out.println("Category size: " + list.size());
Hibernate: select category0_.id as id1_, category0_.created_on as created2_1_, category0_.name as name1_ from category category0_ where category0_.name=? Category size: 1
We can determine from the output that hibernate will get a query using the name
parameter shown in Line 1
. We set a named parameter, "name"
, using the setString(…)
method shown in Line 2
.
The value in the name
parameter should be unique to the application. If hibernate finds a value of a parameter multiple times, it will throw an error. This is similar to "Duplicate query mapping getCategoryNameByName"
, if the name getCategoryNameByName
were defined multiple times in an application.
Now, let's take a look at how to use @NamedQueries
to define multiple NamedQueries.
In the previous section, we created NamedQuery for "getCategoryNameByName"
. Now, we need one more query, such as "getCategoryNameById"
. Let's take a look at how to define it:
Source file: Category.java
@NamedQueries( { @NamedQuery( name="getCategoryNameByName", query="FROM Category c WHERE c.name=:name" ), @NamedQuery( name="getCategoryNameById", query="FROM Category c WHERE c.id=:id" ), } ) @Entity @Table(name = "category") public class Category { // fields and getters/setters }
This works in the same way as @NamedQuery
. This is only used to define multiple NamedQueries.