Here is some code that I have written.. you may need to make your own static factory methods to generate the criteria instances from the supplied session.
The first class DoubleCriteria internally manages two identical criteria instances. You use it like this :
DoubleCriteria dc = DoubleCriteria.createDoubleCriteria(session, Person.class)
The second class CountDoubleCriteria extends DoubleCriteria. It is to allow you to generate a page of data by obtaining a list and a count.
CountDoubleCriteria supresses any Criteria methods that are unacceptable in generating a count - setProjection, addOrder etc..
Its not perfect, however it is a fairly clean soloution.
Code:
/**
* @author CameronBraid
*
*/
public class DoubleCriteria implements Criteria {
protected Criteria a, b;
public Criteria getA() {
return a;
}
public Criteria getB() {
return b;
}
public static DoubleCriteria createDoubleCriteria(Session session, Class clazz) {
return new DoubleCriteria(session.createCriteria(clazz), session.createCriteria(clazz));
}
protected DoubleCriteria(Criteria a, Criteria b) {
this.a = a;
this.b = b;
}
public Criteria add(Criterion arg0) {
a.add(arg0);
b.add(arg0);
return this;
}
public Criteria addOrder(Order arg0) {
a.addOrder(arg0);
b.addOrder(arg0);
return this;
}
public Criteria createAlias(String arg0, String arg1) throws HibernateException {
return new DoubleCriteria(a.createAlias(arg0, arg1), b.createAlias(arg0, arg1));
}
public Criteria createCriteria(String arg0) throws HibernateException {
return new DoubleCriteria(a.createCriteria(arg0), b.createCriteria(arg0));
}
public Criteria createCriteria(String arg0, String arg1) throws HibernateException {
return new DoubleCriteria(a.createCriteria(arg0, arg1), b.createCriteria(arg0, arg1));
}
public boolean equals(Object obj) {
return a.equals(obj);
}
public String getAlias() {
return a.getAlias();
}
public int hashCode() {
return a.hashCode() + b.hashCode();
}
public List list() throws HibernateException {
return a.list();
}
public ScrollableResults scroll() throws HibernateException {
return a.scroll();
}
public ScrollableResults scroll(ScrollMode arg0) throws HibernateException {
return a.scroll(arg0);
}
public Criteria setCacheable(boolean arg0) {
a.setCacheable(arg0);
b.setCacheable(arg0);
return this;
}
public Criteria setCacheMode(CacheMode arg0) {
a.setCacheMode(arg0);
b.setCacheMode(arg0);
return this;
}
public Criteria setCacheRegion(String arg0) {
a.setCacheRegion(arg0);
b.setCacheRegion(arg0);
return this;
}
public Criteria setComment(String arg0) {
a.setComment(arg0);
b.setComment(arg0);
return this;
}
public Criteria setFetchMode(String arg0, FetchMode arg1) throws HibernateException {
a.setFetchMode(arg0, arg1);
b.setFetchMode(arg0, arg1);
return this;
}
public Criteria setFetchSize(int arg0) {
a.setFetchSize(arg0);
b.setFetchSize(arg0);
return this;
}
public Criteria setFirstResult(int arg0) {
a.setFirstResult(arg0);
b.setFirstResult(arg0);
return this;
}
public Criteria setFlushMode(FlushMode arg0) {
a.setFlushMode(arg0);
b.setFlushMode(arg0);
return this;
}
public Criteria setLockMode(String arg0, LockMode arg1) {
a.setLockMode(arg0, arg1);
b.setLockMode(arg0, arg1);
return this;
}
public Criteria setLockMode(LockMode arg0) {
a.setLockMode(arg0);
b.setLockMode(arg0);
return this;
}
public Criteria setMaxResults(int arg0) {
a.setMaxResults(arg0);
b.setMaxResults(arg0);
return this;
}
public Criteria setProjection(Projection arg0) {
a.setProjection(arg0);
b.setProjection(arg0);
return this;
}
public Criteria setResultTransformer(ResultTransformer arg0) {
a.setResultTransformer(arg0);
b.setResultTransformer(arg0);
return this;
}
public Criteria setTimeout(int arg0) {
a.setTimeout(arg0);
a.setTimeout(arg0);
return this;
}
public String toString() {
return a.toString();
}
public Object uniqueResult() throws HibernateException {
return a.uniqueResult();
}
}
Code:
public static CountDoubleCriteria createDoubleCriteria(Session session, Class clazz) {
return new CountDoubleCriteria(session.createCriteria(clazz), session.createCriteria(clazz));
}
protected CountDoubleCriteria(Criteria a, Criteria b) {
super(a,b);
}
public Criteria setFirstResult(int arg0) {
a.setFirstResult(arg0);
return this;
}
public Criteria setMaxResults(int arg0) {
a.setMaxResults(arg0);
return this;
}
public Criteria addOrder(Order arg0) {
a.addOrder(arg0);
return this;
}
public Criteria setProjection(Projection arg0) {
if (!(arg0 instanceof PropertyProjection)) {
throw new HibernateException("count double criteria only supports specification of a PropertyProjection");
}
a.setProjection(arg0);
return this;
}
public Page createPage(Range range) {
if (range != null) {
getB().setProjection(Projections.rowCount());
Integer count = (Integer)getB().uniqueResult();
getA().setMaxResults(range.getPageSize());
getA().setFirstResult(range.getFirstRow()-1);
List list = getA().list();
return new Page(list, range, count);
} else {
List list = getA().list();
return new Page(list, range, list.size());
}
}
}