Jan 8, 2014

Named Query and Named Native Query with annotations

We will use Bean, Utilty and DAO classes created in last article for basic hibernate configuration then we will use two features of Hibernate called named query and named native query for fetching list of employees filtered by their first name.

Named Query: We map Hibernate Query to some logical name and use this name to get required results.
Named Native Query: We map raw JDBC query to some logical name and use this name to get required results.

So we will use same EmployeeDAO and EmployeeBean for this example. We will use following annotations for configuring these queries in hibernate

@NamedQueries: List of named queries
@NamedQuery: To map hibernate query to its logical name.
@NamedNativeQueries: List of named native queries
@NamedNativeQuery: To map raw/native JDBC query to its logical name.

We will start with Named Query and then there is a minor change that we will make to use named native query. So we will add @NamedQueries tag and in its argument we will pass list of queries with annotations @NamedQuery.

@NamedQueries({
       @NamedQuery(name="get-emp-by-name",query="FROM EmployeeBean WHERE fName=:fName")
})

And in DAO class we will add one method that will accept name and return list of EmployeeBean.

public List<EmployeeBean> getEmployeeListByName(String name){
       Session sess = null;
       try{
              sess = HibernateUtil.getSession();
              Query qry = sess.getNamedQuery("get-emp-by-name"); //Get the query
              qry.setString("fName", name); //Set the parameter
              System.out.println(qry.getQueryString()); //Check what query is fetched
              return qry.list(); //Return the list of results
       }
       catch(HibernateException e){
              e.printStackTrace();//Later remove this by appropriate logger statement or throw custom exception
       }
       finally{
              HibernateUtil.closeSession(sess);
       }
       return null;
}

When this code is executed it will give following result.

Jan 08, 2014 7:41:14 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
Jan 08, 2014 7:41:14 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.0.Final}
Jan 08, 2014 7:41:14 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Jan 08, 2014 7:41:14 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Jan 08, 2014 7:41:14 PM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: /hibernate.cfg.xml
Jan 08, 2014 7:41:14 PM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: /hibernate.cfg.xml
Jan 08, 2014 7:41:15 PM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
Jan 08, 2014 7:41:15 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Jan 08, 2014 7:41:15 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/northwind]
Jan 08, 2014 7:41:15 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=root, password=****}
Jan 08, 2014 7:41:15 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
Jan 08, 2014 7:41:15 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Jan 08, 2014 7:41:15 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Jan 08, 2014 7:41:15 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
Jan 08, 2014 7:41:15 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
Jan 08, 2014 7:41:15 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
FROM EmployeeBean WHERE fName=:fName
Hibernate: select employeebe0_.EmployeeID as Employee1_0_, employeebe0_.FirstName as FirstNam2_0_, employeebe0_.LastName as LastName3_0_ from employees employeebe0_ where employeebe0_.FirstName=?
[com.techcielo.hibernate43.bean.EmployeeBean@116639]


You can overwrite toString method to print appropriate details of this bean.

Now to use Named native query we will use following annotation in our Bean class. Note that in addition to name and query we also need to tell hibernate that which class it need to use for storing results returned by this query. J

@NamedNativeQueries(
       {
              @NamedNativeQuery(
                     name="get-emp-by-name-native",
                     query="SELECT * FROM Employees WHERE firstName=:fName",
                     resultClass=EmployeeBean.class)
       }
)

Now to use this native query we need to change only parameter get-emp-by-name to get-emp-by-name-native. Hmm….thats all…run the code J

Jan 08, 2014 7:52:49 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
Jan 08, 2014 7:52:49 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.0.Final}
Jan 08, 2014 7:52:49 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Jan 08, 2014 7:52:49 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Jan 08, 2014 7:52:49 PM org.hibernate.cfg.Configuration configure
INFO: HHH000043: Configuring from resource: /hibernate.cfg.xml
Jan 08, 2014 7:52:49 PM org.hibernate.cfg.Configuration getConfigurationInputStream
INFO: HHH000040: Configuration resource: /hibernate.cfg.xml
Jan 08, 2014 7:52:49 PM org.hibernate.cfg.Configuration doConfigure
INFO: HHH000041: Configured SessionFactory: null
Jan 08, 2014 7:52:49 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Jan 08, 2014 7:52:49 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/northwind]
Jan 08, 2014 7:52:49 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=root, password=****}
Jan 08, 2014 7:52:49 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
Jan 08, 2014 7:52:49 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Jan 08, 2014 7:52:49 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Jan 08, 2014 7:52:49 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
Jan 08, 2014 7:52:50 PM org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
Jan 08, 2014 7:52:50 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
SELECT * FROM Employees WHERE firstName=:fName
Hibernate: SELECT * FROM Employees WHERE firstName=?
[com.techcielo.hibernate43.bean.EmployeeBean@fde079]



The difference of these two approaches can be seen in queries that are printed by SOP statements.