Wednesday, January 11, 2012

Named Queries in Hibernate


Named queries
============

It lets you separate queries from coding section of the application to the mapping xml file. The query is given unique name for the entire application. The application can use the query by using the name of the query. This way the application is able to use the same query multiple times without writing the same query multiple times.

Hibernate come out a technique called “names queries” , it lets developer to put all HQL into the XML mapping file or via annotation.

Steps to configure Named queries
==========================

1)    Creating a named query in XML
==============================
The named Query can be  Included in HBM or xml files, However if you include in a separate xml file the Hibernate grammar should be followed.
        
            <?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping
             PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

      <hibernate-mapping>
            <!-- FULL JOIN -->
          <query name="FullJoin"><![CDATA[
            from Supplier s RIGHT JOIN s.products]]>
         </query>
     </hibernate-mapping>

Note:

1)     You can place a named query inside ‘hibernate-mapping‘ element, but do not put before the ‘class‘ element, Hibernate will prompt invalid mapping file, all your named queries have to put after the ‘class‘ element.

2)     Regarding the CDATA, it’s always good practice to wrap your query text with CDATA, so that the XML   parser will not prompt error for some special XML characters like ‘>’ , <’ and etc.

 2)  Calling a Named Query in Java
  =================================
Query query = session.getNamedQuery("FullJoin ");
List results = query.list();


Sending  named parameter
=====================

In XML
======
<query name="HQLpricing">
<![CDATA[from Product product  where product.price < :price or product.id=:id]]>
</query>  

Here Price and id are parameters

In java
=======

Query query = session.getNamedQuery("HQLpricing");
query.setString("price", "25");
query.setString("id", "2");
List<Product> results = query.list();

Sample SQL Named Query
=======================

<sql-query name="findStockByStockCodeNativeSQL">
      <return alias="stock" class="Product"/>
      <![CDATA[select * from product p where p.price < :price]]>
</sql-query>

Note : In native SQL, We have to declare the ‘resultClass‘ to let Hibernate know what is the return type, failed to do it will caused the exception “org.hibernate.cfg.NotYetImplementedException
    
Sending parameters is same in SQL and HQl.

Conclusion
===========

Named queries are global access, which means the name of a query have to be unique in XML mapping files or annotations. In real environment, it’s always good practice to isolate all the named queries into their own file. In addition, named queries stored in the Hibernate mapping files or annotation are more easier to maintain than queries scattered through the Java code.

No comments: