session.createCriteria(User.class)
. setProjection(Projection.property(\"username\"))
.list();
would do exactly what we want. Of course we can also use projection for multiple properties, and combine it with all the other existing features of the Criteria API. For example
session.createCriteria(User.class).setProjection(
Projections.propertyList()
.add(Projection.property(\"firstname\"))
.add(Projection.property(\"lastname\"))
)
.add(Restriction.gt(\"age\", 25))
.list();
would give us the firstnames and lastnames of all users with an age larger than 25. We can also use aggregation - if we want to count the number of users with lastname “Black”, we can use
session.createCriteria(User.class)
.setProjection(Projections.rowCount())
.add(Restriction.eq(\"lastname\", \"Black\"))
.list();
we can even use grouping and projection on associated objects:
session.createCriteria(User.class)
.createAlias(\"roles\", \"r\")
.setProjection( Projections.projectionList()
.add(Projection.groupProperty(\"r.name\"))
.add(Projection.rowCount())
)
.list();
This criteria query gives us the number of users, grouped by role names. With the new Criteria API extensions, you can also construct “detatched criteria” instances, which you can build outside of the session scope, and later use for querying. For example
DetatchedCriteria dc = DetatchedCriteria.forClass(User.class)
.add(Property.forName(\"firstname\").eq(\"John\")
.setProjection(Property.forName(\"age\").min());
Session session = sessionFactory.openSession();
dc.getExecutableCriteria(session).list();
would give use the age of the youngest user named John. You can even use the detatched criteria for building subqueries. For example
DetatchedCriteria dc = DetatchedCriteria.forClass(User.class)
.add(Property.forName(\"firstname\").eq(\"John\")
.setProjection(Property.forName(\"age\").min());
session.createCriteria(User.class)
.add(Subqueries.propertyEq(\"age\", dc))
.list();
would give us all Users which have the same age as the youngest User named John.
Alltogether the new H3 criteria API now is featurewise just as powerful as the HQL query language. If you want to try and experiment with it, download the newest Hibernate 3 beta from the Hibernate website