5 Replies Latest reply on May 12, 2009 11:18 AM by Juan Gonzalez

    Problems with dataTable using ExtendedDataModel

    Gana Prasad Newbie

      Hi,
      I want to test whether the dataTable is providing the lazyloading using extendedDataModel or not.? for that i have written some code. but getting some errors as "Caused by: java.lang.NullPointerException at org.richfaces.demo.extendeddatamodel.DerbyDataModel.getRowCount(DerbyDataModel.java:79)"

      I am sending my code. Pls review the code and tell me where was the problem. Here i am not using any DAO's since i am doing for testing only so i have used the queries directly in the dataProvider class. Please find my code below.


      DerbyDataModel.java:
      --------------------------
      package org.richfaces.demo.extendeddatamodel;

      import java.io.IOException;
      import java.sql.ResultSet;
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;

      import javax.faces.context.FacesContext;

      import org.ajax4jsf.model.DataVisitor;
      import org.ajax4jsf.model.Range;
      import org.ajax4jsf.model.SequenceRange;
      import org.ajax4jsf.model.SerializableDataModel;
      /**
      *
      * @author ias
      * This is example class that intended to demonstrate use of ExtendedDataModel and SerializableDataModel.
      * This implementation intended to be used as a request scope bean. However, it actually provides serialized
      * state, so on a post-back we do not load data from the data provider. Instead we use data that was used
      * during rendering.
      * This data model must be used together with Data Provider, which is responsible for actual data load
      * from the database using specific filtering and sorting. Normally Data Provider must be in either session, or conversation
      * scope.
      */
      public class DerbyDataModel extends SerializableDataModel {

      private DerbyDataProvider dataProvider;
      private Integer currentPk;
      private Map<Integer,DerbyItem> wrappedData = new HashMap<Integer,DerbyItem>();
      private List wrappedKeys = null;

      /**
      *
      */
      private static final long serialVersionUID = -1956179896877538628L;

      /**
      * This method never called from framework.
      * (non-Javadoc)
      * @see org.ajax4jsf.model.ExtendedDataModel#getRowKey()
      */
      @Override
      public Object getRowKey() {
      return currentPk;
      }
      /**
      * This method normally called by Visitor before request Data Row.
      */
      @Override
      public void setRowKey(Object key) {
      this.currentPk = (Integer) key;

      }
      /**
      * This is main part of Visitor pattern. Method called by framework many times during request processing.
      */
      @Override
      public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
      int firstRow = ((SequenceRange)range).getFirstRow();
      int numberOfRows = ((SequenceRange)range).getRows();
      wrappedKeys = new ArrayList();
      for (DerbyItem item:dataProvider.getItemsByrange(new Integer(firstRow), numberOfRows, null, true)) {
      wrappedKeys.add(item.getPk());
      wrappedData.put(item.getPk(), item);
      visitor.process(context, item.getPk(), argument);
      }
      }
      /**
      * This method must return actual data rows count from the Data Provider. It is used by pagination control
      * to determine total number of data items.
      */
      private Integer rowCount; // better to buffer row count locally
      @Override
      public int getRowCount() {
      if (rowCount==null) {
      rowCount = new Integer(getDataProvider().getRowCount());
      return rowCount.intValue();
      } else {
      return rowCount.intValue();
      }
      }
      /**
      * This is main way to obtain data row. It is intensively used by framework.
      * We strongly recommend use of local cache in that method.
      */
      @Override
      public Object getRowData() {
      if (currentPk==null) {
      return null;
      } else {
      DerbyItem ret = wrappedData.get(currentPk);
      if (ret==null) {
      ret = getDataProvider().getDemoDataByPk(currentPk);
      wrappedData.put(currentPk, ret);
      return ret;
      } else {
      return ret;
      }
      }
      }

      /**
      * Unused rudiment from old JSF staff.
      */
      @Override
      public int getRowIndex() {
      throw new UnsupportedOperationException();
      }

      /**
      * Unused rudiment from old JSF staff.
      */
      @Override
      public Object getWrappedData() {
      throw new UnsupportedOperationException();
      }

      /**
      * Never called by framework.
      */
      @Override
      public boolean isRowAvailable() {
      if (currentPk==null) {
      return false;
      } else {
      return getDataProvider().hasDerbyItemByPk(currentPk);
      }
      }

      /**
      * Unused rudiment from old JSF staff.
      */
      @Override
      public void setRowIndex(int rowIndex) {
      throw new UnsupportedOperationException();
      }

      /**
      * Unused rudiment from old JSF staff.
      */
      @Override
      public void setWrappedData(Object data) {
      throw new UnsupportedOperationException();
      }

      /**
      * This method suppose to produce SerializableDataModel that will be serialized into View State and used on a post-back.
      * In current implementation we just mark current model as serialized. In more complicated cases we may need to
      * transform data to actually serialized form.
      */
      public SerializableDataModel getSerializableModel(Range range) {
      if (wrappedKeys!=null) {
      return this;
      } else {
      return null;
      }
      }
      /**
      * This is helper method that is called by framework after model update. In must delegate actual database update to
      * Data Provider.
      */
      @Override
      public void update() {
      getDataProvider().update();
      }

      public DerbyDataProvider getDataProvider() {
      return dataProvider;
      }

      public void setDataProvider(DerbyDataProvider dataProvider) {
      this.dataProvider = dataProvider;
      }

      }


      DerbyDataProvider.java:
      -----------------------------

      package org.richfaces.demo.extendeddatamodel;

      import java.sql.Connection;
      import java.sql.ResultSet;
      import java.sql.ResultSetMetaData;
      import java.sql.SQLException;
      import java.sql.Statement;
      import java.util.ArrayList;
      import java.util.List;
      //import java.util.ArrayList;
      //import java.util.List;

      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import javax.sql.DataSource;

      //import org.richfaces.demo.common.RandomDataHelper;


      public class DerbyDataProvider {

      private ResultSet demoData;
      private ResultSet demoCount;
      private List rs;

      public ResultSet getDemoData() {
      return demoData;
      }

      public void setDemoData(ResultSet demoData) {
      this.demoData = demoData;
      }
      @SuppressWarnings("unchecked")
      public DerbyDataProvider()
      {
      Connection conn1 = null;
      Connection conn2 = null;
      demoData = null;
      demoCount = null;
      try {
      Context initContext = new InitialContext();
      Context envContext = (Context)initContext.lookup("java:/comp/env");
      DataSource ds = (DataSource)envContext.lookup("jdbc/derby");
      conn1 = ds.getConnection();
      conn2 = ds.getConnection();
      Statement stmt1 = conn1.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
      Statement stmt2 = conn2.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
      demoData = stmt1.executeQuery("select * from webscript.demodata");
      demoCount = stmt2.executeQuery("select count(*) from webscript.demodata");
      demoData.absolute(100);
      rs = (List) demoData;
      } catch (NamingException e) {
      e.printStackTrace();
      } catch (SQLException e) {
      e.printStackTrace();
      }

      }
      public int getRowCount() {
      int rc = 0;
      try{
      rc = Integer.parseInt(demoCount.getString(1));
      }catch (SQLException e) {
      e.printStackTrace();
      }
      return rc;
      }

      public List getItemsByrange(Integer startPk, int numberOfRows, String sortField, boolean ascending) {
      List ret = new ArrayList();
      for (int counter=0; counter<numberOfRows; counter++) {
      ret.add(rs.get(startPk.intValue()+counter));
      }
      return ret;
      }
      public DerbyItem getDemoDataByPk(Integer pk) {
      for (DerbyItem item:rs) {
      if (item.getPk().equals(pk)) {
      return item;
      }
      }
      throw new RuntimeException("DerbyItem pk="+pk.toString()+" not found");
      }

      public boolean hasDerbyItemByPk(Integer pk) {
      for (DerbyItem item:rs) {
      if (item.getPk().equals(pk)) {
      return true;
      }
      }
      return false;

      }
      public void update() {
      // nothing need to do
      }

      }


      DerbyItem.java:
      -------------------
      package org.richfaces.demo.extendeddatamodel;

      public class DerbyItem {
      private Integer pk;
      private String PERIOD_START_TIME;
      private String TYPE;
      private String BTS_INT_ID;
      private String BSC_INT_ID;
      private String BSC_NAME;
      private String BTS_NAME;
      private String PERIOD_DURATION;
      private String CONNECTS;
      private String ERRORS;
      private String BYTES;

      @SuppressWarnings("unused")
      private DerbyItem() {};

      public DerbyItem(Integer pk) {
      this.pk = pk;
      }

      public Integer getPk() {
      return pk;
      }

      public String getPERIOD_START_TIME() {
      return PERIOD_START_TIME;
      }

      public void setPERIOD_START_TIME(String period_start_time) {
      PERIOD_START_TIME = period_start_time;
      }

      public String getTYPE() {
      return TYPE;
      }

      public void setTYPE(String type) {
      TYPE = type;
      }

      public String getBTS_INT_ID() {
      return BTS_INT_ID;
      }

      public void setBTS_INT_ID(String bts_int_id) {
      BTS_INT_ID = bts_int_id;
      }

      public String getBSC_INT_ID() {
      return BSC_INT_ID;
      }

      public void setBSC_INT_ID(String bsc_int_id) {
      BSC_INT_ID = bsc_int_id;
      }

      public String getBSC_NAME() {
      return BSC_NAME;
      }

      public void setBSC_NAME(String bsc_name) {
      BSC_NAME = bsc_name;
      }

      public String getBTS_NAME() {
      return BTS_NAME;
      }

      public void setBTS_NAME(String bts_name) {
      BTS_NAME = bts_name;
      }

      public String getPERIOD_DURATION() {
      return PERIOD_DURATION;
      }

      public void setPERIOD_DURATION(String period_duration) {
      PERIOD_DURATION = period_duration;
      }

      public String getCONNECTS() {
      return CONNECTS;
      }

      public void setCONNECTS(String connects) {
      CONNECTS = connects;
      }

      public String getERRORS() {
      return ERRORS;
      }

      public void setERRORS(String errors) {
      ERRORS = errors;
      }

      public String getBYTES() {
      return BYTES;
      }

      public void setBYTES(String bytes) {
      BYTES = bytes;
      }


      }


      If any one can help are very much appreciated..

      Thanks in Advance,
      Gana.










        • 1. Re: Problems with dataTable using ExtendedDataModel
          Juan Gonzalez Newbie

           

          private Integer rowCount; // better to buffer row count locally
          @Override
          public int getRowCount() {
          if (rowCount==null) {
          rowCount = new Integer(getDataProvider().getRowCount());
          return rowCount.intValue();
          } else {
          return rowCount.intValue();
          }
          }
          

          May be dataProvider is null. Because you are testing it must initialize with some value (like lazy loading like this)

          
          public DerbyDataProvider getDataProvider() {
          if (dataProvider==null){
           dataProvider=new DerbyDataProvider();
          }
          return dataProvider;
          }
          
          


          • 2. Re: Problems with dataTable using ExtendedDataModel
            Gana Prasad Newbie

            Hi,
            Thanks for your quick reply. Now i am getting the rowcount value but how to get the resultset values in the walk method. I have assigned the resultset values to one list and i am sending but i am getting the following exception."java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingResultSet cannot be cast to java.util.List"

            I am sending my dataProvider class. Plese find below. In my previous post in DerbyModel i have removed the sort and selection fileds since i don't want those.


            DerbyDataProvider.java:
            -----------------------------


            package org.richfaces.demo.extendeddatamodel;

            import java.sql.Connection;
            import java.sql.ResultSet;
            import java.sql.SQLException;
            import java.sql.Statement;
            import java.util.ArrayList;
            import java.util.List;
            //import java.util.ArrayList;
            //import java.util.List;

            import javax.naming.Context;
            import javax.naming.InitialContext;
            import javax.naming.NamingException;
            import javax.sql.DataSource;

            //import org.richfaces.demo.common.RandomDataHelper;


            public class DerbyDataProvider {

            private ResultSet demoData;
            private ResultSet demoCount;
            int rowCount =0;
            private List rs;

            public ResultSet getDemoData() {
            return demoData;
            }

            public void setDemoData(ResultSet demoData) {
            this.demoData = demoData;
            }

            public ResultSet getDemoCount() {
            return demoCount;
            }

            public void setDemoCount(ResultSet demoCount) {
            this.demoCount = demoCount;
            }

            public DerbyDataProvider()
            {
            Connection conn1 = null;
            demoData = null;
            try {
            Context initContext = new InitialContext();
            Context envContext = (Context)initContext.lookup("java:/comp/env");
            DataSource ds = (DataSource)envContext.lookup("jdbc/derby");
            conn1 = ds.getConnection();
            Statement stmt1 = conn1.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            demoData = stmt1.executeQuery("select * from webscript.demodata");
            System.out.println("Gana demoData:"+demoData);
            demoData.absolute(100);
            while(demoData.next())
            {
            rowCount++;
            }
            System.out.println("Gana rowCount:"+rowCount);
            } catch (NamingException e) {
            e.printStackTrace();
            } catch (SQLException e) {
            e.printStackTrace();
            }

            }
            public int getRowCount() {
            return rowCount;
            }

            @SuppressWarnings("unchecked")
            public List getItemsByrange(Integer startPk, int numberOfRows) {
            List ret = new ArrayList();
            rs = (List) demoData;
            for (int counter=0; counter<numberOfRows; counter++) {
            ret.add(rs.get(startPk.intValue()+counter));
            }
            return ret;
            }
            public DerbyItem getDemoDataByPk(Integer pk) {
            for (DerbyItem item:rs) {
            if (item.getPk().equals(pk)) {
            return item;
            }
            }
            throw new RuntimeException("DerbyItem pk="+pk.toString()+" not found");
            }

            public boolean hasDerbyItemByPk(Integer pk) {
            for (DerbyItem item:rs) {
            if (item.getPk().equals(pk)) {
            return true;
            }
            }
            return false;

            }
            public void update() {
            // nothing need to do
            }

            }



            Thanks in Advance,
            Gana.

            • 3. Re: Problems with dataTable using ExtendedDataModel
              Juan Gonzalez Newbie

               

              @SuppressWarnings("unchecked")
              public List getItemsByrange(Integer startPk, int numberOfRows) {
              List ret = new ArrayList();
              rs = (List) demoData;
              for (int counter=0; counter<numberOfRows; counter++) {
              ret.add(rs.get(startPk.intValue()+counter));
              }
              return ret;
              }


              As you can see above demoData isn't a List interface, I guess this is a ResultSet object (returned by executeQuery). So you cannot cast that way.



              • 4. Re: Problems with dataTable using ExtendedDataModel
                Gana Prasad Newbie

                Hi,
                Even if i changed it to List i am getting the same error.

                • 5. Re: Problems with dataTable using ExtendedDataModel
                  Juan Gonzalez Newbie

                  Please think a little and take your time before doing anything with no sense. This is a beginner's question that has nothing to do with Richfaces.

                  Didn't understad me. DemoData IS a ResultSet, and that is correct.

                  You have to return a List object, so you have to iterate through DemoData, adding DerbyItem to an ArrayList and return that ArrayList. Very simple.