Hibernate Criteria Detached Query And Subquery
In this tutorial you will learn about Detached Query and Subquery in Criteria Query.
Hibernate provides the facility to write the query aside from the session scope and get executed it in an arbitrary Session. Writing query apart from the scope of Session facility is provided by the Hibernate using org.hibernate.criterion.DetachedCriteria class this class may be used in anywhere in the code. To fetch Criteria a Session may be passed in the getExecutableCriteria() method, this method is executed within a Session.
for example :
DetachedCriteria query = DetachedCriteria.forClass(Employee.class); query.add(Property.forName("gender").eq("m")); ............... ............... ............... session= sessionFactory.openSession(); Transaction tx = session.beginTransaction(); Listls = query.getExecutableCriteria(session).list(); Iterator it = ls.iterator();
A subquery can also be expressed using DetachedCriteria. (Click Here for Criteria Detached Subquery example).
Example
Below I am giving an example which will demonstrate you how to write a query outside a session scope. In this example basic works are done as we were doing in our previous examples such as creation of table in the database where the data has to be persisted then creation of POJO/ Persistent class for persisting the persistent object a hibernate mapping file that maps the class properties with the corresponding table fields. A configuration mapping file creation that provides the information to the Hibernate to create the connection pool and their respective required environment set up. And finally creation of a main class where we will write the query to fetch data from the table. After execution of this example will return the data from table employeename whose gender is matched to 'm'.
Table employeename
create table employeename ( id int (10) not null, name varchar (15) default null, gender varchar (5) default null, primary key (id) )
Employee.java
package roseindia; public class Employee { private int id; private String name; private String gender; public Employee() { } public Employee(String name, String gender) { this.name = name; this.gender = gender; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
Employee.hbm.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate mapping DTD//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name= "roseindia.Employee" table="employeename"> <id name= "id" type="int" > <generator class="native" /> </id> <property name="name" /> <property name="gender" /> </class> </hibernate-mapping>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://192.168.10.13:3306/data </property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.current_session_context_class">thread</property> </session-factory> </hibernate-configuration>
HibernateDetachedQueriesExample.java
package roseindia; import java.util.Iterator; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Property; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; public class HibernateDetachedQueriesExample { private static SessionFactory sessionFactory = null; private static ServiceRegistry serviceRegistry = null; public static void main(String args[]) { Session session = null; try { Configuration cfg = new Configuration().addResource("roseindia/Employee.hbm.xml"); cfg.configure(); serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry(); sessionFactory = cfg.buildSessionFactory(serviceRegistry); } catch(Throwable th) { System.err.println("Failed to create sessionFactory object." + th); throw new ExceptionInInitializerError(th); } DetachedCriteria query = DetachedCriteria.forClass(Employee.class); query.add(Property.forName("gender").eq("m")); try{ session= sessionFactory.openSession(); Transaction tx = session.beginTransaction(); List<Employee> ls = query.getExecutableCriteria(session).list(); Iterator<Employee> it = ls.iterator(); System.out.println("Id \t name"); while(it.hasNext()) { Employee emp = (Employee)it.next(); System.out.println(emp.getId()+"\t "+emp.getName()); } session.close(); tx.commit(); } catch(Exception e) { System.out.println(e.getMessage()); } } }
Output :
1. table employeename
2. When you will execute the java file HibernateDetachedQueriesExample.java (RightClick -> Run As -> Java Application) the query generated by Hibernate and the output will be displayed on your console as :
Query generated by Hibernate :
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions) Mar 22, 2012 3:20:56 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init> INFO: HHH000397: Using ASTQueryTranslatorFactory Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.gender as gender0_0_ from employeename this_ where this_.gender=?
output on console will be as follows :