4 Replies Latest reply on Mar 4, 2011 12:12 PM by Ilya Sorokoumov

    Methods walk, totalRow in rich:dataTable executed several times after one action

    Vitek Panasyuk Newbie

      I add rich:dataTable to the page and add ExtendedDataModel, but methods walk, totalRow executed several times. Our request to server send long time....How to make in right way mechanism for ignore duplicate requests.

        • 1. Methods walk, totalRow in rich:dataTable executed several times after one action
          Rocky S Master

          make your rich:dataTable component as Factory component if you are using Seam.

          • 2. Methods walk, totalRow in rich:dataTable executed several times after one action
            Ilya Sorokoumov Master

            Method walk is executed several times during one request. It's ok. It's a part of JSF implementation. You can write your own implementation of ExtendedDataModel in order to limit count of select queries during one request(I've done it in my app because I didn't want it to perform unnecessary queries).

            • 3. Re: Methods walk, totalRow in rich:dataTable executed several times after one action
              Vitek Panasyuk Newbie

              Why RichFaces team don't create this implementation. Please post your implementation, or ssend to v_panasyuk@i.ua. It save my time. Thanks

              • 4. Re: Methods walk, totalRow in rich:dataTable executed several times after one action
                Ilya Sorokoumov Master

                Here you are(You can also find an interesting discussion here http://community.jboss.org/message/577751?tstart=0):

                package ccgproj.web.faces.lazy;



                import java.io.IOException;

                import java.io.Serializable;

                import java.util.ArrayList;

                import java.util.HashMap;

                import java.util.List;

                import java.util.Map;

                import java.util.UUID;



                import javax.el.ELException;

                import javax.el.Expression;

                import javax.el.ValueExpression;

                import javax.faces.FacesException;

                import javax.faces.context.FacesContext;

                import javax.swing.SortOrder;



                import org.ajax4jsf.model.DataVisitor;

                import org.ajax4jsf.model.ExtendedDataModel;

                import org.ajax4jsf.model.Range;

                import org.ajax4jsf.model.SequenceRange;

                import org.hibernate.criterion.Order;

                import org.richfaces.model.FilterField;

                import org.richfaces.model.Modifiable;

                import org.richfaces.model.Ordering;

                import org.richfaces.model.SortField2;




                * @author sorokoumov


                public abstract class ModifiableDataModel<T> extends ExtendedDataModel implements Modifiable, Serializable {



                    private final String dataModelID = UUID.randomUUID().toString();



                    private T dataItem;

                    private SequenceRange cachedRange;

                    private List<T> cachedItems;

                    private List<SortField2> sortFields;

                    private Map<String, SortOrder> sortOrders = new HashMap<String, SortOrder>();

                    private Integer rowCount;



                    public Map<String, SortOrder> getSortOrders() {

                        return sortOrders;




                    public void setSortOrders(Map<String, SortOrder> sortOrders) {

                        this.sortOrders = sortOrders;




                    public ModifiableDataModel() {





                    private static boolean areEqualRanges(SequenceRange range1, SequenceRange range2) {

                        if (range1 == null || range2 == null) {

                            return range1 == null && range2 == null;

                        } else {

                            return range1.getFirstRow() == range2.getFirstRow() && range1.getRows() == range2.getRows();





                    protected List<Order> getOrder(FacesContext context) {

                        List<Order> orders = new ArrayList<Order>();

                        if (sortFields != null) {

                            for (SortField2 sortField : sortFields) {

                                Ordering ordering = sortField.getOrdering();



                                if (Ordering.ASCENDING.equals(ordering) || Ordering.DESCENDING.equals(ordering)) {

                                    String propertyName = getPropertyName(context, sortField.getExpression());



                                    Order order = Ordering.ASCENDING.equals(ordering)

                                            ? Order.asc(propertyName) : Order.desc(propertyName);





                        return orders;




                    private String getPropertyName(FacesContext facesContext, Expression expression) {

                        try {

                            return (String) ((ValueExpression) expression).getValue(facesContext.getELContext());

                        } catch (ELException e) {

                            throw new FacesException(e.getMessage(), e);






                    public Object getRowKey() {

                        return dataItem;





                    public void setRowKey(Object key) {

                        this.dataItem = (T)key;






                    public void walk(FacesContext facesContext, DataVisitor visitor, Range range,

                            Object argument) throws IOException {



                        SequenceRange sequenceRange = (SequenceRange) range;



                        if (this.cachedItems == null || !areEqualRanges(this.cachedRange, sequenceRange)) {

                            int first = sequenceRange.getFirstRow();

                            int rows = sequenceRange.getRows();



                            this.cachedRange = sequenceRange;

                            this.cachedItems = findItemsByRange(first, first + rows);




                        for (T item : this.cachedItems) {

                            visitor.process(facesContext, item, argument);






                    public int getRowCount() {

                        Map<String, Object> map = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();

                        if (rowCount == null || map.get(dataModelID + "_asked") == null) {

                            rowCount = new Integer(findRowCount());

                            map.put(dataModelID + "_asked", "");


                        return rowCount.intValue();





                    public Object getRowData() {

                        return this.dataItem;





                    public int getRowIndex() {

                        return -1;





                    public Object getWrappedData() {

                        return null;





                    public boolean isRowAvailable() {

                        return (this.dataItem != null);





                    public void setRowIndex(int rowIndex) {





                    public void setWrappedData(Object data) {





                    public void modify(List<FilterField> filterFields, List<SortField2> sortFields) {

                        //ignore filterFields

                        //save sortFields

                        this.sortFields = sortFields;

                        this.cachedItems = null;

                        this.cachedRange = null;




                    public abstract int findRowCount();



                    public abstract List<T> findItemsByRange(int firstRow, int endRow);



                    public abstract Object getKey(T obj);