Hibernate and JPA Named Query example

This article is a walkthrough the Hibernate and JPA Named Query interface and how you can use it to externalize common

Hibernate and JPA specification lets you externalize query strings to the mapping Metadata, a technique that is called named queries. This allows you to store all queries related to a particular persistent class (or a set of classes) in an XML mapping file or using some simple annotations.

Hibernate example:

Supposing that you have the following query in the Hibernate Query Language (HQL):

"from Customer c where c.name like :cname"

We can introduce this query in the file Customer.hbm.xml, using the <query> element:

<query name="findCustomerByName"><![CDATA[from Customer c where c.name like :cname]] />

Notice: Named queries don’t have to be HQL strings; they might even be native SQL queries: learn more here: How to use native Queries in JPA ?

And here’s how to use your Named Query:

session.getNamedQuery("findCustomerByName")
.setString("cname", name)
.list();

JPA Example:

Named queries are typically placed on the Entity class that most directly corresponds to the query result, so the Customer Entity would be a good location for this named query

@NamedQuery(name="findCustomerByName",
query="from Customer c where c.name like :cname")

Then in your EJB, you can use:

@Stateless
public class CustomerServiceBean  {

@PersistenceContext(unitName="CustomerService")
EntityManager em;

   public Customer findCustomerByName(String name) {
     return em.createNamedQuery("findCustomerByName",Customer.class)
       .setParameter("name", name)
       .getSingleResult();
   }
// ...
}

Besides, you can also declare a NamedQuery in the file src/main/resources/META-INF/orm.xml file. For example:

<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
                                     http://xmlns.jcp.org/xml/ns/persistence/orm_2_0.xsd" version="2.1">

    <!-- JPA Named Queries -->
    <named-query name="Customers.findAll">
        <query>SELECT c FROM Customer c ORDER BY c.id</query>
    </named-query>
    

    <!-- entity mapping -->
    <entity class="com.sample.Account">
        <attributes>
            <basic name="title"/>
        </attributes>
    </entity>

</entity-mappings>

How to define a Named Query programmatically

You can also create a Named Query programmatically with the EntityManagerFactory#addNamedQuery() method. For example:

Query customerQuery = em.createQuery("select c from Customer c");
em.getEntityManagerFactory().addNamedQuery("customerQuery", customerQuery);
Query query = em.createNamedQuery("customerQuery");

Setting a Named Query hint

Finally, the Java Persistence API defines the notion of query hint, which in spite of what its name might suggest, it has nothing to do with database query hints. The JPA query hint is a Java Persistence provider customization option.

A common example, is to include a Query Timeout or a Query Comment. For example:

@NamedQueries({
@NamedQuery(
name = "findItemByName",
query = "select i from Item i where i.name like :name",
hints = {
@QueryHint(
name = org.hibernate.annotations.QueryHints.TIMEOUT_JPA, value = "60000"),
@QueryHint(
name = org.hibernate.annotations.QueryHints.COMMENT, value = "Custom SQL comment")
}
)
})
Found the article helpful? if so please follow us on Socials