Introduction
You may have heard this several times that databases are the need for the future. Traditional File System usage has declined extensively. People have realized that managing and working with databases is much easier. When dealing with databases, we just cannot neglect the queries used to manage those databases. An Object-Relational mapping framework, especially for Java programming language, is what we call Hibernate. It is a tool that can be used to map object-oriented domain models to a relational database. It is a free-of-cost software, and its primary feature is to map Java classes to database tables and Java data types to querying datatypes. Hibernate also comes with querying and retrieval facilities.
Hibernate Named Query
A static HQL or SQL query with a fixed query string and defined either using annotation @NamedQuery or an XML file is known as Named Query. If it is an HQL query, it is called Hibernate Named Query, while if it is an SQL query, it is called Structured Named Query. If we want to execute named queries, we will refer to a named query by its name during runtime.
The Named Queries are preferred only for the selection of records based on complex conditions. Therefore, these queries are not used frequently. The output of these named queries is not cached in the secondary memory, but only the query object itself is cached.
Advantages
The Named Queries make the grouping of HQL statements in a single place easy. These queries are later referred to using pre-configured names whenever needed. To learn about the advantages of named queries, refer to the list below.
- Helps in Code Cleanup.
- No longer confusion.
- Fails faster in case of errors saving time.
- Reusability.
- The cost of transformation is negligible.
- Caching cost is really small.
Creation of Named Query
We will demonstrate the declaration of a Named Query using the StudentEntity. We will create a simple named query that fetches a student by its id.
The two important attributes used in the definition of a Named Query are name and query.
@NamedQuery(name = "QUERY_GET_STUDENT_BY_ID", query = DepartmentEntity.QUERY_GET_STUDENT_BY_ID)
@Entity
public class StudentEntity implements Serializable
{
public static final String QUERY_GET_STUDENT_BY_ID = "QUERY_GET_STUDENT_BY_ID";
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
Configuring Named Query Features
With the @NamedQuery annotation, we can set several query features. To understand these features better, refer to the example below.
@org.hibernate.annotations.NamedQuery(
class = "StudentClass_FindAllByStudent",
q = "from StudentClass where student = :student",
timeout = 2,
fetchSize = 20
)
In the example above, we have configured only the two features, that is, the timeout interval and the fetch size. Leaving these two, we can also set features which are mentioned in the list below.
- cacheable
- cacheMode
- cacheRegion
- comment
- flushMode
Grouping Named Query
In case we have multiple queries for a particular entity, we can group them using the annotation ‘@NamedQueries’.
The code below shows how the grouping will be implemented.
@NamedQueries({
@NamedQuery(name = "QUERY_GET_STUDENT_BY_ID", query = "from StudentEntity s where s.id = :id"), @NamedQuery(name = "QUERY_UPDATE_STUDENT_BY_ID", query= "UPDATE StudentEntity s SET s.name=:name where s.id = :id")
})
@Entity
public class StudentEntity implements Serializable
{
public static final String QUERY_GET_STUDENT_BY_ID = "QUERY_GET_STUDENT_BY_ID";
public static final String QUERY_UPDATE_STUDENT_BY_ID
= "QUERY_UPDATE_STUDENT_BY_ID";
//...
}
Execution of Named Query
If you want to execute any Named Query, then you should use the createNamedQuery() method which will help you create a Query Instance. Then we will use this instance to create an interface. This interface will help you execute an SQL query.
The below code shows how to implement the createNamedQuery() method and execute a Named Query.
@Test
public void getEntityById() {
Query q= em.createNamedQuery (StudentEntity.QUERY_GET_STUDENT_BY_ID).setParameter("id", 1);
StudentEntity student = (StudentEntity) q.getSingleResult();
Assertions.assertEquals("HR", student.getName());
}
Named Native Query
The Named Native Queries annotated as ‘NamedNativeQuery’ works very similar to NamedQuery. The single difference is that we have to write native SQL statements instead of HQL statements.
To understand Named Native Query better, refer to the following example.
@NamedNativeQueries({
@NamedNativeQuery(name = "NATIVE_QUERY_GET_STUDENT_BY_ID",
q = "SELECT * FROM TBL_STUDENT s WHERE s.id = :id"),
@NamedNativeQuery(name = "NATIVE_QUERY_UPDATE_STUDENT_BY_ID",
q = "UPDATE TBL_STUDENT s SET s.name=:name WHERE s.id = :id")
})
Stored Procedures and Functions
We will use the @NamedNativeQuery annotation that will define calls to stored procedures as well as functions in the manner below:
@org.hibernate.annotations.NamedNativeQuery(name = "Student_UpdateMarks", query = "call UPDATE_MARKS(:studentID, :newMarks)", resultClass = Student.class)
You should pay attention that although this is an update query, we've used the resultClass property. This is because Hibernate doesn't support pure native scalar queries. And the way to work around the problem is to either set a resultClass or a resultSetMapping.




