This example is similar to Tapestry5HibernateGridDatasource, but uses Hibernate Criteria API for filtering and the Session directly without DAO.

to use it inside your page injest these .. and add this method:

   1     @Inject private ComponentResources _resources;    
   2     @Inject private Session _session;
   3 
   4 public GridDataSource getVessels(){
   5     HibernateEntityDataSource<Vessel> vessels = HibernateEntityDataSource.create(_session,Vessel.class, _resources);
   6     if(vesselName != null && !"".equals(vesselName.trim())) vessels.addCriterion(Restrictions.like("name", vesselName+"%"));
   7     return vessels;
   8 }

and add grid to te template:

<t:grid source="vessels"/>

if you have a search form, number of items will change for different search criteria, so make sure you reset pager in that case. Something like this:

   1     @Component private Grid grid;
   2     
   3     public void onSubmit(){
   4         grid.setCurrentPage(1);
   5     }

the ComponentResources is there if you want to have an event when sorting happens... this way you can add default sort (Although I would recommend setting default sort through the grid so the sorted column is displayed correctly, but if default sort column is not visible in grid, then this is the place to do it). This GridDataSource will call "sortColumn" event that you can catch like this:

   1 public void onSortColumn(Criteria crit, String order, boolean asc){
   2     if(order != null){
   3         if(order.equals("date")){
   4             crit.addOrder(asc ? Order.asc("num") : Order.desc("num"));
   5         }
   6     }else{
   7         //default sort here 
   8     }
   9 }

and of course the source for the GridDataSource

   1 import java.util.List;
   2 
   3 import org.apache.tapestry.ComponentResources;
   4 import org.apache.tapestry.beaneditor.PropertyModel;
   5 import org.apache.tapestry.grid.GridDataSource;
   6 import org.hibernate.Criteria;
   7 import org.hibernate.Session;
   8 import org.hibernate.criterion.Criterion;
   9 import org.hibernate.criterion.Order;
  10 import org.hibernate.criterion.Projections;
  11 import org.hibernate.criterion.Restrictions;
  12 
  13 /** Grid data source that queries hibernate. It caches count and results, and is not suitable for reuse.*/
  14 public class  HibernateEntityDataSource<T> implements GridDataSource {
  15 
  16     private final Class<T> persistentClass;
  17     private final Session _session;
  18     private final Criteria criteria;
  19 
  20     /** cached data */
  21     protected List<T> data;
  22     /** count value cached on first call to {@link #getAvailableRows()}*/
  23     protected int count=-1;
  24     /** we will select only part of the table so later when asked for a row, we use this to offset the index*/
  25     protected int startIndex=0;
  26     private ComponentResources _resources;
  27     
  28     /** A datasource for grid. Provide {@link ComponentResources} and "sortColumn" event will be triggered 
  29      * from the {@link #prepare(int, int, PropertyModel, boolean)} method.*/
  30     @SuppressWarnings("unchecked")
  31     public HibernateEntityDataSource(Session session, Class<T> type, ComponentResources resources){
  32         super();
  33         _session = session;
  34         persistentClass = type;
  35         _resources = resources;
  36         criteria = _session.createCriteria(persistentClass);
  37     }
  38     
  39     public static final <T> HibernateEntityDataSource<T> create(Session session,Class<T> type, ComponentResources resources){
  40         return new HibernateEntityDataSource<T>(session,type, resources);
  41     }
  42 
  43     /** this value is cached on first access so do not add filters after it is called*/
  44     public int getAvailableRows() {
  45         if(count == -1){
  46             criteria.setProjection(Projections.rowCount());
  47             count =((Integer)criteria.list().get(0)).intValue();
  48             criteria.setProjection(null);
  49             criteria.setResultTransformer(Criteria.ROOT_ENTITY);
  50         }
  51         return count;
  52     }
  53 
  54     public Class<T> getRowType() {
  55         return persistentClass;
  56     }
  57     /** Add a creterion to filter results. for example: {@link Restrictions#eq(String, Object)}*/
  58     public void addCriterion(Criterion criterion){
  59         criteria.add(criterion);
  60     }
  61 
  62     /** The index must be between startIndex and endIndex provided in {@link #prepare(int, int, List<SortConstraint>)} implemented from {@link GridDataSource#prepare(int, int, List<SortConstraint>)}*/
  63     public Object getRowValue(int index) {
  64         return data.get(index-startIndex);
  65     }
  66 
  67     @SuppressWarnings("unchecked")
  68     public void prepare(int startIndex, int endIndex, List<SortConstraint> sortConstraints) {
  69         //query is much faster if we take only results we need. it can be up to 10x faster even for a small table with 1000 records
  70         criteria.setFirstResult(startIndex);
  71         criteria.setMaxResults(endIndex-startIndex+1);
  72         this.startIndex = startIndex;
  73 
  74         for (SortConstraint sortConstraint : sortConstraints) {
  75             String sortColumnName = sortConstraint.getPropertyModel().getPropertyName();
  76             boolean ascending = (sortConstraint.getColumnSort()==ColumnSort.ASCENDING);
  77             Order order = ascending ? Order.asc(sortColumnName) : Order.desc(sortColumnName);
  78             criteria.addOrder(order);
  79             if(_resources != null) _resources.triggerEvent("sortColumn", new Object[]{criteria,sortColumnName, ascending, persistentClass},null);
  80         }
  81 
  82         data = criteria.list();
  83     }
  84 }

Tapestry5HibernateGridDatasource2 (last edited 2009-09-20 23:20:42 by localhost)