-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Clining a Criteria
PostPosted: Thu Mar 10, 2005 2:09 pm 
Beginner
Beginner

Joined: Thu Aug 26, 2004 5:53 am
Posts: 37
I wish to be able to create a clone of a Criteria object.

I need this to be able to do criteria based pagination easier.

i.e. a criteria instance for the list and one for the projection (count)

I can think of a workaround by creating a DoubleCriteriaCriterion instance that uses two internal criteria instances delegating all method calls to both instances.

However, I don't see any issue with hibernate supporting the ability to clone a Criteria.

Any thoughts ?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 10, 2005 3:09 pm 
Newbie

Joined: Tue Mar 01, 2005 10:37 am
Posts: 17
I'm working on the same thing. See this thread for the current status: http://forum.hibernate.org/viewtopic.ph ... 71#2233971


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 10, 2005 4:48 pm 
Newbie

Joined: Tue Mar 01, 2005 10:37 am
Posts: 17
My current solution is (very ugly) to create the Criteria twice, and pass them both in to my pagination-handling class. One criteria is used for getting a page of data, the other criteria is used to get the count.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 12, 2005 9:29 am 
Beginner
Beginner

Joined: Thu Aug 26, 2004 5:53 am
Posts: 37
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());
         
      }

    }

}


Top
 Profile  
 
 Post subject:
PostPosted: Sat Mar 12, 2005 9:31 am 
Beginner
Beginner

Joined: Thu Aug 26, 2004 5:53 am
Posts: 37
I missed the first line of CountDoubleCriteria

i'll paste it all again.

Code:
public class CountDoubleCriteria extends DoubleCriteria {

   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());
         
      }

    }

}
[/code]


Top
 Profile  
 
 Post subject: Clone it! hey man its Serializable.
PostPosted: Mon Mar 14, 2005 10:15 pm 
Newbie

Joined: Wed Feb 23, 2005 11:57 am
Posts: 15
You can copy or clone any object that implements Serializable. :)

Below is an example clone for a DetachedCriteria. You could do Criteria interface instead but then you would have to cast it to its implementation to call setSession(..) at some point.

I have no idea if this is a good idea or not. I would like to hear from people if this is really bad. :)

And yes, I did this for pagination.

Code:
protected DetachedCriteria copy(DetachedCriteria criteria) {
        try {
            ByteArrayOutputStream baostream = new ByteArrayOutputStream();
            ObjectOutputStream oostream = new ObjectOutputStream(baostream);
            oostream.writeObject(criteria);
            oostream.flush();
            oostream.close();
            ByteArrayInputStream baistream = new ByteArrayInputStream(baostream.toByteArray());
            ObjectInputStream oistream = new ObjectInputStream(baistream);
            DetachedCriteria copy = (DetachedCriteria)oistream.readObject();
            oistream.close();           
            return copy;
        } catch(Throwable t) {
            throw new HibernateException(t);
        }
    }


Top
 Profile  
 
 Post subject: Re: Clone it! hey man its Serializable.
PostPosted: Thu Oct 13, 2005 12:52 pm 
Newbie

Joined: Tue Mar 15, 2005 1:38 pm
Posts: 11
Hello...

I've been doing the same thing you suggested but I discovered an instance where DetachedCriteria can't be successfully serialized. That is, when doing a criteria by Example... The Example object contains some internal classes which aren't serializable. :( So I guess I have to use one of the other workarounds.

(And yes, I'm also doing this for pagination.)

Corey

gabrielh wrote:
You can copy or clone any object that implements Serializable. :)

Below is an example clone for a DetachedCriteria. You could do Criteria interface instead but then you would have to cast it to its implementation to call setSession(..) at some point.

I have no idea if this is a good idea or not. I would like to hear from people if this is really bad. :)

And yes, I did this for pagination.



Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.