You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Apache Wiki <wi...@apache.org> on 2008/02/06 09:51:28 UTC

[Tapestry Wiki] Update of "Tapestry5HibernateGridDatasource2" by DavorHrg

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for change notification.

The following page has been changed by DavorHrg:
http://wiki.apache.org/tapestry/Tapestry5HibernateGridDatasource2

New page:
This example is similar to Tapestry5HibernateGridDatasource, but uses Hibernate Criteria API for filtering
and the Session directly without DAO.
 * it loads only the results that will be shown in the grid
 * it calculates count from the provided criteria
 * it caches result from the count query so an instance is not reusable (but can be made so)


to use it inside your page injest these .. and add this method:
{{{#!java
    @Inject private ComponentResources _resources;    
    @Inject private Session _session;

public GridDataSource getVessels(){
    HibernateEntityDataSource<T> documents = HibernateEntityDataSource.create(_session,Vessel.class, _resources);
    if(vesselName != null && !"".equals(vesselName.trim())) list.addCriterion(Restrictions.like("name", vesselName+"%"));
    return vessels;
}
}}}

and add grid to te template:
{{{
<t:grid source="vessels"/>
}}}

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:

{{{#!java
public void onSortColumn(Criteria crit, String order, boolean asc){
    if(order != null){
        if(order.equals("date")){
            crit.addOrder(asc ? Order.asc("num") : Order.desc("num"));
        }
    }else{
        //default sort here 
    }
}
}}}

and of course the source for the !GridDataSource

{{{#!java
import java.util.List;

import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.beaneditor.PropertyModel;
import org.apache.tapestry.grid.GridDataSource;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

/** Grid data source that queries hiberante. It caches count and results, and is not suitable for reuse.*/
public class  HibernateEntityDataSource<T> implements GridDataSource {

    private final Class<T> persistentClass;
    private final Session _session;
    private final Criteria criteria;

    /** cached data */
    protected List<T> data;
    /** count value cached on first call to {@link #getAvailableRows()}*/
    protected int count=-1;
    /** we will select only part of the table so later when asked for a row, we use this to offset the index*/
    protected int startIndex=0;
    private ComponentResources _resources;
    
    /** A datasource for grid. Provide {@link ComponentResources} and "sortColumn" event will be triggered 
     * from the {@link #prepare(int, int, PropertyModel, boolean)} method.*/
    @SuppressWarnings("unchecked")
    public HibernateEntityDataSource(Session session, Class<T> type, ComponentResources resources){
        super();
        _session = session;
        persistentClass = type;
        _resources = resources;
        criteria = _session.createCriteria(persistentClass);
    }
    
    public static final <T> HibernateEntityDataSource<T> create(Session session,Class<T> type, ComponentResources resources){
        return new HibernateEntityDataSource<T>(session,type, resources);
    }

    /** this value is cached on first access so do not add filters after it is called*/
    public int getAvailableRows() {
        if(count == -1){
            criteria.setProjection(Projections.rowCount());
            count =((Integer)criteria.list().get(0)).intValue();
            criteria.setProjection(null);
            criteria.setResultTransformer(Criteria.ROOT_ENTITY);
        }
        return count;
    }

    public Class<T> getRowType() {
        return persistentClass;
    }
    /** Add a creterion to filter results. for example: {@link Restrictions#eq(String, Object)}*/
    public void addCriterion(Criterion criterion){
        criteria.add(criterion);
    }

    /** The index must be between startIndex and endIndex provided in {@link #prepare(int, int, PropertyModel, boolean)} implemented from {@link GridDataSource#prepare(int, int, PropertyModel, boolean)}*/
    public Object getRowValue(int index) {
        return data.get(index-startIndex);
    }

    @SuppressWarnings("unchecked")
    public void prepare(int startIndex, int endIndex, PropertyModel sortModel, boolean ascending) {
        //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
        criteria.setFirstResult(startIndex);
        criteria.setMaxResults(endIndex-startIndex+1);
        this.startIndex = startIndex;

        String sortColumnName = null;
        if(sortModel != null){
            sortColumnName = sortModel.getPropertyName();
            Order order = ascending ? Order.asc(sortColumnName) : Order.desc(sortColumnName);
            criteria.addOrder(order);
        }
        if(_resources != null) _resources.triggerEvent("sortColumn", new Object[]{criteria,sortColumnName, ascending, persistentClass},null);

        data = criteria.list();
    }
}

}}}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org