3 Replies Latest reply on May 20, 2002 10:51 AM by Bani Greyling

    Find Top 5 records

    Bani Greyling Newbie

      Hi

      JBoss-2.4.4 on MSSql Server

      I would like to find the top 5 entity beans using CMP. So I have implemented the finder method myself, which return a collection of PK's.

      Here is my query:
      String query = "SELECT TOP 5 ShipperId, ConsigneeId, GenesisUserId FROM dbo.Consignee where GenesisUserId = ? order by LastUsed DESC";

      This works all fine, but when I update one of the properties of the bean and call on my custom finder implementation again, it gets a bean from somewhere that does not contain the changed property. It seems to me that it creates a new on from the database. If I wait until the bean has bean pasivated, it reflects the property change. I think it is a sync problem before the load takes place.

      Anyone have some inputs?

      Regards
      Bani

        • 1. Find Top 5 records
          Bani Greyling Newbie

          Things look a more serious...I hope I am missing something somewhere...

          JBoss-2.4.4 on MSSqlServer 2000

          If I have a table like
          create table mytable (col1 char(10),col2 char(10),col3 char(10)) such that col1,col2 is the primary key. The database (MSSQL 2000) is of such a nature that a value selected from a char column with a length longer than the original inserted value will be return with the total length of the field.

          My primary key class impl looks like
          public boolean equals(Object obj) {
          if (this.getClass().equals(obj.getClass())) {
          ConsigneePK that = (ConsigneePK) obj;
          return this.col1.trim().equals(that.col1.trim()) && this.col2.trim().equals(that.col2.trim()));
          }
          return false;
          }

          If I do a finder like
          SomeRemote remote1 = home.findByPrimaryKey(new mytablePK("1000","1000"));

          and then

          SomeRemote remote2 = home.findByPrimaryKey(new mytablePK("1000 ","1000 "));

          I, correctly find that remote1.isIdentical(remote2) returns true and that remote1.getPrimaryKey().equals(remote2.getPrimaryKey()) returns true.

          But if I do this
          SomeRemote remote1 = home.findByPrimaryKey(new mytablePK("1000","1000"));
          remote1.setCol3("value_1");

          and then
          SomeRemote remote2 = home.findByPrimaryKey(new mytablePK("1000 ","1000 "));

          I find that remote2.getCol3().equals("value_1") does NOT evalute to true.

          I also find in the logfile that two beans of this type get passivate, although there should only be one.

          Does anyone have an idea.


          • 2. Re: Find Top 5 records
            Bani Greyling Newbie

            Hi

            On my previous post lines like this one (notice "remote2")

            > SomeRemote remote2 = home.findByPrimaryKey(new
            > mytablePK("1000 ","1000 "));

            actually have space where the following example have underscores

            > SomeRemote remote2 = home.findByPrimaryKey(new
            > mytablePK("1000______","1000______"));

            The spaces is there, but not apparent.

            • 3. Re: Find Top 5 records
              Bani Greyling Newbie

              Hi
              I think I got to the source of the problem...

              All Intity Bean lookups in the org.jboss.ejb.plugins.EntityInstanceCache is done using instances of org.jboss.ejb.CacheKey. The cache key override the primary key's hashcode and equals methods with:

              in constructor is the following codefragment:

              mo = new java.rmi.MarshalledObject(id);
              hashCode = mo.hashCode();

              CacheKey hashcode implementation
              public int hashCode()
              {
              // we default to the pK id
              return hashCode;
              }

              CacheKey equals implementation
              public boolean equals(Object object)
              {
              if (object instanceof CacheKey)
              {
              return (mo.equals(((CacheKey) object).mo));
              }
              return false;
              }

              This results in the following codefragment:

              ConsigneePK pk1 = new ConsigneePK("QAAI","1001","USERAI");
              ConsigneePK pk2 = new ConsigneePK("QAAI ","1001 ","USERAI "); // <-- Contains one space each after QAAI,1001 and USERAI
              MarshalledObject pk1Mar = new MarshalledObject(pk1);
              MarshalledObject pk2Mar = new MarshalledObject(pk2);
              System.out.println("Equals: " + pk1.equals(pk2));
              System.out.println("Same Hash: " + (pk1.hashCode() == pk2.hashCode()));
              System.out.println("Marshalled Equals: " + pk1Mar.equals(pk2Mar));
              System.out.println("Marshalled Hash: " + (pk1Mar.hashCode() == pk2Mar.hashCode()));

              producing the result:

              Equals: true
              Same Hash: true
              Marshalled Equals: false
              Marshalled Hash: false

              This all boils down to the fact that I could never be sure to get the same RemoteEntity bean based on the implementation of my primary key.

              Hope some can give their experiances