Friday, 3 May 2013

Hibernate Projections

Projections in Hibernate

 Projections are a part of Hibernate 3.0 onwards. In general Projection means to retrieve partial objects which are similar to "Select" clause of SQL Projection. With the help of projections we can use Database Aggregate functions.Like:- From the Student pojo, I want to retrieve the column values of firstName and Division of all the records available in the table.
So for the above scenario we can go with the below code:-
                               
                                ProjectionList projectionList = Projections.projectionList();
                                projectionList.add(Projections.property("firstName"));
                                projectionList.add(Projections.property("division"));
                                criteria5.setProjection (projectionList);

Projection interface is available in “org.hibernate.criterion” package, where as Projectionsand ProjectionList classes are available in same package. Projections is a factory class responsible for producing projection objects. All the static methods are available in Projections class.
Below is the summary for Projections class static methods:-




If we want to add a Projection object to Criteria then we have to call a setProjection() method as below:-
criteria5.setProjection (projectionList);

Demo Example for how to use projection in hibernate:-

Steps:-
  • For the creation of java project:- please refer the below link:-

  • For the table creation and records insertion please follow the below link:-

  • For knowing the project structure and library files follow the below link:-

  • For Hibernate configuration file, hibernate mapping file and java beans we can follow below link:-

  • Create a client program for implementing hibernate projection with name UseOfHibernateProjection.java and place it in the com.gaurav.hibernate.projection package.

package com.gaurav.hibernate.projection;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;

import com.gaurav.hibernate.beans.Student;



public class UseOfHibernateProjection {
    @SuppressWarnings({ "rawtypes"})
    public static void main(String[] args) {

        Session session = null;

        try {

            SessionFactory sessionFactory = new Configuration().configure()
                    .buildSessionFactory();
            session = sessionFactory.openSession();
           
           
            Criteria criteria1 = session.createCriteria(Student.class);
           
            /** To get average of the specified property from the DB table.
            *   Similarly we can use SUM function here.*/

           
            criteria1.setProjection(Projections.avg("totalMarks"));
            List resultAvgList = criteria1.list();
            System.out.println("********** USE OF AVG FUNCTION CRITERIA PROJECTION API IN HIBERNATE **********");
            System.out.println("Average total marks is : " + resultAvgList.get(0));
           
           
            Criteria criteria2 = session.createCriteria(Student.class);
           
            /** To get total number of row count for mapped table.
            *   Similary we can use countDistinct() function here.*/

           
            criteria2.setProjection(Projections.rowCount());
            List resultRowCountList = criteria2.list();
            System.out.println("********** USE OF ROWCOUNT FUNCTION CRITERIA PROJECTION API IN HIBERNATE **********");
            System.out.println("Total Number of records are : " + resultRowCountList.get(0));
           
       
            Criteria criteria3 = session.createCriteria(Student.class);
           
            /** To get distinct count of the property property from the DB table. */
           
            criteria3.setProjection(Projections.countDistinct("firstName"));
            List resultCountDistinctList = criteria3.list();
            System.out.println("********** USE OF COUNTDISTINCT FUNCTION CRITERIA PROJECTION API IN HIBERNATE **********");
            System.out.println("Distinct Row Count is : " + resultCountDistinctList.get(0));
           
           
            Criteria criteria4 = session.createCriteria(Student.class);
            /** To get maximum of the specified property from the DB table.
            *   Similarly we can min function here.*/
            criteria4.setProjection(Projections.max("totalMarks"));
            List resultMaxList = criteria4.list();
            System.out.println("********** USE OF MAX FUNCTION CRITERIA PROJECTION API IN HIBERNATE **********");
            System.out.println("Max in total marks is : " + resultMaxList.get(0));
           
            Criteria criteria5 = session.createCriteria(Student.class);
           
            ProjectionList projectionList = Projections.projectionList();
            projectionList.add(Projections.property("firstName"));
            projectionList.add(Projections.property("division"));
            criteria5.setProjection(projectionList);
           
            List resultProjectionList = criteria5.list();
            Iterator iterator = resultProjectionList.iterator();
            System.out.println("\t FIRSTNAME"+" DIVISION");
           
            if(resultProjectionList != null){
                while(iterator.hasNext()){
                 System.out.println("\n");
                 Object[] recordsRow = (Object[])iterator.next();
                 for(int i = 0; i < recordsRow.length;i++){
                 System.out.print("\t"+recordsRow[i]);
                            
                }
            }
        }
           
            /** How to add projection properties in the list at once and how to use group by
              * and order by functionality with projection */

           
            System.out.println("\n\n");
            List allProjectionInOneresultList = session.createCriteria(Student.class)
            .setProjection( Projections.projectionList()
                .add( Projections.rowCount() )
                .add( Projections.avg("totalMarks") )
                .add( Projections.max("totalMarks") )
                .add( Projections.groupProperty("firstName") ) //group by functionality.
            )
             .addOrder( Order.desc("firstName") ) //order by functionality.
            .list();
            Iterator iterator1 = allProjectionInOneresultList.iterator();
           
            if(allProjectionInOneresultList != null){
                while(iterator1.hasNext()){
                 System.out.println("\n");
                 Object[] recordsRow = (Object[])iterator1.next();
                 for(int i = 0; i < recordsRow.length;i++){
                 System.out.print("\t"+recordsRow[i]);
                            
                }
            }
        }
           
            System.out.println("\n\n");
           
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();

        }
    }
}

Result:- 

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
 
Hibernate: select avg(this_.TOTAL_MARKS) as y0_ from Student this_
 
********** USE OF AVG FUNCTION CRITERIA PROJECTION API IN HIBERNATE **********
 
Average total marks is : 767.8182
Hibernate: select count(*) as y0_ from Student this_

********** USE OF ROWCOUNT FUNCTION CRITERIA PROJECTION API IN HIBERNATE **********
 
Total Number of records are : 11
Hibernate: select count(distinct this_.FIRSTNAME) as y0_ from Student this_

********** USE OF COUNTDISTINCT FUNCTION CRITERIA PROJECTION API IN HIBERNATE **********
 
Distinct Row Count is : 11
Hibernate: select max(this_.TOTAL_MARKS) as y0_ from Student this_

********** USE OF MAX FUNCTION CRITERIA PROJECTION API IN HIBERNATE **********
 
Max in total marks is : 995
Hibernate: select this_.FIRSTNAME as y0_, this_.DIVISION as y1_ from Student this_
     
FIRSTNAME        DIVISION


    Kumar                FIRST

    Gaurav             FIRST

    Shivam          SECOND

    Hemant           FIRST

    Rimi               SECOND

    Ram              SECOND

    Hansika         THIRD

    Maduri          THIRD

    Mili                THIRD

    Aaditya         FIRST

    Amit               FIRST

********** USE OF MUTIPLE AGGREGATE FUNCTIONS WITH GROUP BY CLAUSE OF PROJECTION API IN HIBERNATE **********
 
Hibernate: select count(*) as y0_, avg(this_.TOTAL_MARKS) as y1_, max(this_.TOTAL_MARKS) as y2_, this_.FIRSTNAME as y3_ from Student this_ group by this_.FIRSTNAME order by this_.FIRSTNAME desc


    1    670.0    670    Shivam

    1    657.0    657    Rimi

    1    750.0    750    Ram

    1    566.0    566    Mili

    1    578.0    578    Maduri

    1    920.0    920    Kumar

    1    900.0    900    Hemant

    1    590.0    590    Hansika

    1    880.0    880    Gaurav

    1    940.0    940    Amit

    1    995.0    995    Aaditya

No comments:

Post a Comment