3 Replies Latest reply on Aug 29, 2001 8:22 PM by mkaseman

    right or wrong way to do CMP/SLSB

    mkaseman

      I have been experimenting with a Stateless Session bean invoking a CMP bean. The CMP bean uses a custom PK class, that contains three fields.
      When I run the slsb and invoke the cmp bean, I get the following response times:


      ROWS CTX TIME CMP TIME COL TIME TOTAL TIME
      159.000 0.020 0.881 16.734 17.635
      158.000 0.020 0.831 16.173 17.024
      159.000 0.020 0.821 16.404 17.235
      AVG 158.667 0.020 0.844 16.437 17.298

      The above times are in seconds


      Where CTX is the InitialContext/PortableRemoteObject.narrow time frame. CMP is the actual time of the findByXXXXX method and COL is the time to process the collection using an iterator:

      Sample Code:

      c = homeJobHistStatsListCMP.findByJobNameCompCode(job_name, completion_code);
      i = c.iterator();

      m_dteBeginCOLTimeStamp = new Date();

      while (i.hasNext())
      {
      JobHistStatsListIntfCMP intf = (JobHistStatsListIntfCMP) (i.next());

      JobHistStatsListBeanPK cmpPK = new JobHistStatsListBeanPK (intf.getCompletion_Code(), intf.getJobname(), intf.getRun_Date_Time());

      cReturn.add(cmpPK);
      }

      m_dteEndCOLTimeStamp = new Date();


      Sample ejb-jar:

      <prim-key-class>com.eds.mtv.mvs.ejb.PrimKey.JobHistStatsListBeanPK</prim-key-class>
      <cmp-field><field-name>jobname</field-name></cmp-field>
      <cmp-field><field-name>completion_code</field-name></cmp-field>
      <cmp-field><field-name>run_date_time</field-name></cmp-field>

      Sample PK class:


      package com.eds.mtv.mvs.ejb.PrimKey;

      import java.io.Serializable;
      import java.sql.*;

      public class JobHistStatsListBeanPK extends Object implements Serializable
      {

      public String jobname;
      public String completion_code;
      public Timestamp run_date_time;


      public JobHistStatsListBeanPK () {}

      public JobHistStatsListBeanPK (String code, String jobname, Timestamp runDateTime)
      {
      this.completion_code = code;
      this.jobname = jobname;
      this.run_date_time = runDateTime;
      }

      public JobHistStatsListBeanPK (String code, String jobname, String runDateTime)
      {
      this.completion_code = code;
      this.jobname = jobname;
      this.run_date_time = new Timestamp(0l).valueOf(runDateTime);
      }

      public String getCompletionCode()
      {
      return completion_code;
      }

      public String getJobName()
      {
      return jobname;
      }

      public Timestamp getRunDateTime()
      {
      return run_date_time;
      }

      public boolean equals(Object obj)
      {
      if (obj instanceof JobHistStatsListBeanPK)
      {
      return (completion_code.equals(((JobHistStatsListBeanPK)obj).completion_code)
      && jobname.equals(((JobHistStatsListBeanPK)obj).jobname)
      && run_date_time.equals(((JobHistStatsListBeanPK)obj).run_date_time));

      }

      return false;
      }

      public int hashCode()
      {
      return (completion_code+jobname+run_date_time.toString()).hashCode();
      }

      public String toString()
      {
      return "|"+completion_code+"|"+jobname+"|"+run_date_time.toString()+"|";
      }

      }



      Now this seems like a lot of time to me, spent in processing the collection, since the fields I want are in the PK class. So my first attempts at casting the collection to the PK class failed for ClassCastExceptions. Along the way of trial an error, I did a interface.toString() and discovered the results looked like the data items I wanted. So I added a toString() function on my PK class, but with column delimiters that would allow me to use the StringTokenizer function in my slsb to pull apart the string and rebuild a new collection to return from my slsb. Seems like a lot of slight-of-hand, but look at the new timings!

      Open to comments, criticisms or questions!


      ROWS CTX TIME CMP TIME COL TIME TOTAL TIME
      159.000 0.010 0.998 0.020 1.032
      159.000 0.020 0.871 0.010 0.901
      159.000 0.020 0.901 0.010 0.931
      AVG 159.000 0.017 0.923 0.013 0.955

      Above times are in seconds.



      Modified SLSB Code:


      c = homeJobHistStatsListCMP.findByJobNameCompCode(job_name, completion_code);
      i = c.iterator();

      m_dteBeginCOLTimeStamp = new Date();

      while (i.hasNext())
      {
      JobHistStatsListIntfCMP intf = (JobHistStatsListIntfCMP) (i.next());

      strtkRowData = new StringTokenizer(intf.toString(),COLUMN_DELIMITER);

      if (strtkRowData.countTokens () == NBR_OF_COLUMNS_IN_DATA)
      {
      strtkRowData.nextToken(); //strip off class-name prefix added by interface.toString() ???

      JobHistStatsListBeanPK cmpPK = new JobHistStatsListBeanPK (strtkRowData.nextToken(), strtkRowData.nextToken(), strtkRowData.nextToken());
      cReturn.add(cmpPK);
      }
      }

      m_dteEndCOLTimeStamp = new Date();


        • 1. Re: right or wrong way to do CMP/SLSB
          mkaseman

          After more research into the Collection Interaction time using the P6Spy product, that shows all SQL calls performed. It seems JBOSS does another SQL read for the exact key fields I have in the PK class bean when I access the various CMP getXXXX() methods for a specific instance of the collection.

          I tested the interface.toString() with ORION and I receive the same concatenated string back that I can use the StringTokenizer on to split apart. So this performance enhancement cheating works on two different servers.

          However when I use the P6Spy product with ORION, it does only 1 SQL call for the findByXXXX method, but does not redo any SQL calls for the fields contained in the PK class bean.

          • 2. Re: right or wrong way to do CMP/SLSB
            hraun

            Thanks for this insight.
            Keep it up!
            :-D
            Peet

            • 3. Re: right or wrong way to do CMP/SLSB
              mkaseman

              With help from danch, he pointed out that i should use remote.getPrimaryKey(), if my PK class contains all the data items i need. I made these changes and my response time was around 1.2 secs for 160 rows.