Criteria is a simplified API for retrieving entities by composing Criterion objects. This is a very convenient approach for functionality like “search” screens where there is a variable number of conditions to be placed upon the result set.

Recommended Reading:

Spring Data JPA Specification Criteria Query Example

JPA Criteria API Example

The following example shows how to work with Hibernate Criteria API.


Create MySQL Table

CREATE TABLE `items` (
  `item_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `item_name` varchar(45) COLLATE latin1_general_ci NOT NULL,
  `item_desc` text COLLATE latin1_general_ci,
  `item_price` double unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

 

Insert some data into the items table

insert  into `items`(`item_id`,`item_name`,`item_desc`,`item_price`) values
(1,'CD','CD is a compact disk',100),
(2,'DVD','DVD is larger than CD in size',150),
(3,'ABC','ABC test description',24),
(4,'XYZ','XYZ test description',25.32),
(5,'CD Player','CD player is used to play CD',30.02);

 

Create hibernate.cfg.xml and put under classpath

<?xml version="1.0" encoding="UTF-8"?>
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/cdcol?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">root</property>
    <mapping resource="in/sblog/domain/Items.hbm.xml">
    </mapping>
  </session-factory>
</hibernate-configuration>

 

Create hibernate domain object for items

<?xml version="1.0"?>
<hibernate-mapping>
    <class name="in.sblog.domain.Items" table="items" catalog="cdcol">
        <id name="itemId" type="java.lang.Integer">
            <column name="item_id"></column>
            <generator class="identity"></generator>
        </id>
        <property name="itemName" type="string">
            <column name="item_name" length="45" not-null="true"></column>
        </property>
        <property name="itemDesc" type="string">
            <column name="item_desc" length="65535"></column>
        </property>
        <property name="itemPrice" type="double">
            <column name="item_price" precision="22" scale="0" not-null="true"></column>
        </property>
    </class>
</hibernate-mapping>
public class Items implements java.io.Serializable {
    private Integer itemId;
    private String itemName;
    private String itemDesc;
    private double itemPrice;
    public Items() {
    }
    public Items(String itemName, double itemPrice) {
        this.itemName = itemName;
        this.itemPrice = itemPrice;
    }
    public Items(String itemName, String itemDesc, double itemPrice) {
        this.itemName = itemName;
        this.itemDesc = itemDesc;
        this.itemPrice = itemPrice;
    }
    public Integer getItemId() {
        return this.itemId;
    }
    public void setItemId(Integer itemId) {
        this.itemId = itemId;
    }
    public String getItemName() {
        return this.itemName;
    }
    public void setItemName(String itemName) {
        this.itemName = itemName;
    }
    public String getItemDesc() {
        return this.itemDesc;
    }
    public void setItemDesc(String itemDesc) {
        this.itemDesc = itemDesc;
    }
    public double getItemPrice() {
        return this.itemPrice;
    }
    public void setItemPrice(double itemPrice) {
        this.itemPrice = itemPrice;
    }
}

 

Create HibernateUtil.java class which gives SessionFactory instance

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
/**
 * Hibernate Utility class with a convenient method to get Session Factory
 * object.
 *
 * @author admin
 */
public class HibernateUtil {
    private static final SessionFactory sessionFactory;
    static {
        try {
            // Create the SessionFactory from standard (hibernate.cfg.xml)
            // config file.
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Log the exception.
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

 

Now below one by one snippets show how to work with Criteria

Create a Criteria instance and retrieve the result

public List getAllItems() {
        Transaction tx = null;
        List items = new ArrayList<>();
        try {
            tx = session.beginTransaction();
            //Criteria instance
            Criteria criteria = session.createCriteria(Items.class);
            //get list of items from criteria instance
            items = criteria.list();
        } catch (HibernateException e) {
            if (tx != null) {
                tx.rollback();
            }
            e.printStackTrace();
        } finally {
            if (tx != null) {
                tx.commit();
            }
        }
    return items;
}

 

If you want to limit max result then you can do so using setMaxResult(int max) method.

Criteria criteria = session.createCriteria(Items.class);
criteria.setMaxResults(4);
items = criteria.list();

 

So the above code returns maximum number of four items if there are more than four items.

You can perform Like search using below query

public List getItemsLike(String str) {
        Transaction tx = null;
        Session session = null;
        List items = new ArrayList<>();
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(Items.class);
            //like search
            criteria.add(Restrictions.like("itemDesc", str));
            items = criteria.list();
        } catch (HibernateException e) {
            if (tx != null) {
                tx.rollback();
            }
            e.printStackTrace();
        } finally {
            if (tx != null) {
                tx.commit();
            }
        }
        return items;
    }

 

You can restrict the fetched values using Restriction.between()

public List getItemsRange(String str, int min, int max) {
        Transaction tx = null;
        Session session = null;
        List items = new ArrayList<>();
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(Items.class);
            //like search
            criteria.add(Restrictions.like("itemDesc", str));
            //min and max value for an item id
            criteria.add(Restrictions.between("itemId", min, max));
            items = criteria.list();
        } catch (HibernateException e) {
            if (tx != null) {
                tx.rollback();
            }
            e.printStackTrace();
        } finally {
            if (tx != null) {
                tx.commit();
            }
        }
        return items;
    }

 

Ordering the results either by ascending or descending

public List getItemsByOrder(String property, String order) {
        Transaction tx = null;
        Session session = null;
        List items = new ArrayList<>();
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(Items.class);
            //ascending order
            if ("asc".equalsIgnoreCase(order)) {
                criteria.addOrder(Order.asc(property));
            }
            //descending order
            if ("desc".equalsIgnoreCase(order)) {
                criteria.addOrder(Order.desc(property));
            }
            items = criteria.list();
        } catch (HibernateException e) {
            if (tx != null) {
                tx.rollback();
            }
            e.printStackTrace();
        } finally {
            if (tx != null) {
                tx.commit();
            }
        }
        return items;
    }

 

You can also do the same thing in the following way

Criteria criteria = session.createCriteria(Items.class);
//ascending order
if ("asc".equalsIgnoreCase(order)) {
    criteria.addOrder(Property.forName(property).asc());
}
//descending order
if ("desc".equalsIgnoreCase(order)) {
    criteria.addOrder(Property.forName(property).desc());
}
items = criteria.list();

 

How to restrict the results by equality check

public List getItemsEq(String str) {
        Transaction tx = null;
        Session session = null;
        List items = new ArrayList<>();
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(Items.class);
            //check item name is equal
            criteria.add(Restrictions.eq("itemName", str));
            items = criteria.list();
        } catch (HibernateException e) {
            if (tx != null) {
                tx.rollback();
            }
            e.printStackTrace();
        } finally {
            if (tx != null) {
                tx.commit();
            }
        }
        return items;
    }

 

Testing the Criteria API

import in.sblog.helper.CriteriaHelper;
import java.util.List;

public class TestCriteriaAPI {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        CriteriaHelper ch = new CriteriaHelper();
        List items = ch.getAllItems();
        System.out.println("Total Records: " + items.size());
        System.out.println("--------------------------------");
        items = ch.getItemsLike("%cd%");
        System.out.println("Total Records: " + items.size());
        System.out.println("--------------------------------");
        items = ch.getItemsRange("%cd%", 1, 3);
        System.out.println("Total Records: " + items.size());
        System.out.println("--------------------------------");
        items = ch.getItemsByOrder("itemName", "asc");
        System.out.println("Total Records: " + items.size());
        System.out.println("--------------------------------");
        items = ch.getItemsEq("CD");
        System.out.println("Total Records: " + items.size());
        System.out.println("--------------------------------");
    }
}

 

Output

Hibernate:
    select
        this_.item_id as item1_0_0_,
        this_.item_name as item2_0_0_,
        this_.item_desc as item3_0_0_,
        this_.item_price as item4_0_0_
    from
        cdcol.items this_ limit ?
Total Records: 4
--------------------------------
Hibernate:
    select
        this_.item_id as item1_0_0_,
        this_.item_name as item2_0_0_,
        this_.item_desc as item3_0_0_,
        this_.item_price as item4_0_0_
    from
        cdcol.items this_
    where
        this_.item_desc like ?
Total Records: 3
--------------------------------
Hibernate:
    select
        this_.item_id as item1_0_0_,
        this_.item_name as item2_0_0_,
        this_.item_desc as item3_0_0_,
        this_.item_price as item4_0_0_
    from
        cdcol.items this_
    where
        this_.item_desc like ?
        and this_.item_id between ? and ?
Total Records: 2
--------------------------------
Hibernate:
    select
        this_.item_id as item1_0_0_,
        this_.item_name as item2_0_0_,
        this_.item_desc as item3_0_0_,
        this_.item_price as item4_0_0_
    from
        cdcol.items this_
    order by
        this_.item_name asc
Total Records: 5
--------------------------------
Hibernate:
    select
        this_.item_id as item1_0_0_,
        this_.item_name as item2_0_0_,
        this_.item_desc as item3_0_0_,
        this_.item_price as item4_0_0_
    from
        cdcol.items this_
    where
        this_.item_name=?
Total Records: 1
--------------------------------

Recommended Reading:

Spring Data JPA Specification Criteria Query Example

JPA Criteria API Example

Thanks for your reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit

Leave a Reply

Your email address will not be published. Required fields are marked *