Hibernate now features an intuitive, extensible criteria query API. For now, this API is less powerful and than the more mature HQL query facilities. In particular, criteria queries do not support projection or aggregation.
The interface net.sf.hibernate.Criteria represents a query against a particular persistent class. The Session is a factory for Criteria instances.
Criteria crit = sess.createCriteria(Cat.class); crit.setMaxResults(50); List cats = crit.list();
An individual query criterion is an instance of the interface net.sf.hibernate.expression.Criterion. The class net.sf.hibernate.expression.Expression defines factory methods for obtaining certain built-in Criterion types.
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "Fritz%") ) .add( Expression.between("weight", minWeight, maxWeight) ) .list();
Expressions may be grouped logically.
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "Fritz%") ) .add( Expression.or( Expression.eq( "age", new Integer(0) ), Expression.isNull("age") ) ) .list();
List cats = sess.createCriteria(Cat.class) .add( Expression.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) ) .add( Expression.disjunction() .add( Expression.isNull("age") ) .add( Expression.eq("age", new Integer(0) ) ) .add( Expression.eq("age", new Integer(1) ) ) .add( Expression.eq("age", new Integer(2) ) ) ) ) .list();
There are quite a range of built-in criterion types (Expression subclasses), but one that is especially useful lets you specify SQL directly.
List cats = sess.createCriteria(Cat.class) .add( Expression.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) ) .list();
The {alias} placeholder with be replaced by the row alias of the queried entity.
You may order the results using net.sf.hibernate.expression.Order.
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "F%") .addOrder( Order.asc("name") ) .addOrder( Order.desc("age") ) .setMaxResults(50) .list();
You may easily specify constraints upon related entities by navigating associations using createCriteria().
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "F%") .createCriteria("kittens") .add( Expression.like("name", "F%") .list();
note that the second createCriteria() returns a new instance of Criteria, which refers to the elements of the kittens collection.
The following, alternate form is useful in certain circumstances.
List cats = sess.createCriteria(Cat.class) .createAlias("kittens", "kt") .createAlias("mate", "mt") .add( Expression.eqProperty("kt.name", "mt.name") ) .list();
(createAlias() does not create a new instance of Criteria.)
Note that the kittens collections held by the Cat instances returned by the previous two queries are not pre-filtered by the criteria! If you wish to retrieve just the kittens that match the criteria, you must use returnMaps().
List cats = sess.createCriteria(Cat.class) .createCriteria("kittens", "kt") .add( Expression.eq("name", "F%") ) .returnMaps() .list(); Iterator iter = cats.iterator(); while ( iter.hasNext() ) { Map map = (Map) iter.next(); Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS); Cat kitten = (Cat) map.get("kt"); }
You may specify association fetching semantics at runtime using setFetchMode().
List cats = sess.createCriteria(Cat.class) .add( Expression.like("name", "Fritz%") ) .setFetchMode("mate", FetchMode.EAGER) .setFetchMode("kittens", FetchMode.EAGER) .list();
This query will fetch both mate and kittens by outer join.
The class net.sf.hibernate.expression.Example allows you to construct a query criterion from a given instance.
Cat cat = new Cat(); cat.setSex('F'); cat.setColor(Color.BLACK); List results = session.createCriteria(Cat.class) .add( Example.create(cat) ) .list();
Version properties, identifiers and associations are ignored. By default, null valued properties are excluded.
You can adjust how the Example is applied.
Example example = Example.create(cat) .excludeZeroes() //exclude zero valued properties .excludeProperty("color") //exclude the property named "color" .ignoreCase() //perform case insensitive string comparisons .enableLike(); //use like for string comparisons List results = session.createCriteria(Cat.class) .add(example) .list();
You can even use examples to place criteria upon associated objects.
List results = session.createCriteria(Cat.class) .add( Example.create(cat) ) .createCriteria("mate") .add( Example.create( cat.getMate() ) ) .list();