3 Replies Latest reply on Apr 10, 2004 12:31 PM by semi

    Fastest way from ejbql Collection to ValueObject[]?

    dhartford

      Hey all,
      To date, I have been doing the following to cast my ejbfinder/ejbselects to value objects:

      ==code==
      Collection codes = ahome.findAll();
      MyEntityLocal[] mycodes = (MyEntityLocal[])codes.toArray(new MyEntityLocal[0]);
      
      MyEntityLightValue[] myvo = new MyEntityLightValue[mycodes.length];
      
      for (int i=0; i<mycodes.length; i++){
      
      myvo[ i ] = mycodes[ i ].getMyEntityLightValue();
      }
      ==end code==


      Is there a more efficient/faster way of doing this? I looked into ejbselects to return directly the Value Object Array, but that did not meet with success.

      Any help would be appreciated!
      -D


        • 1. Re: Fastest way from ejbql Collection to ValueObject[]?
          s2ulf

          Hello!

          Take a look at http://www-106.ibm.com/developerworks/java/library/j-santa1/. That example has a good implementation for retrieving value objects. A reminder: you have to take special care in supporting bi-directional relationships when dealing with value objects (e.g. object A has one/many B, B has one/many A) or else it will be reentrant (recursive).

          If you like the way it is implemented in the IBM example, try using XDoclet. It generates everything for you!

          Cheers,
          Ulf
          [/url]

          • 2. Re: Fastest way from ejbql Collection to ValueObject[]?
            semi

            Hi,

            creating an array and copying all items from a collection into it
            is more expensive as a simple iterator walktrough with casts
            on each item.

            Collection codes = ahome.findAll();
            MyEntityLightValue[] myvo = new MyEntityLightValue[codes.size()];
            
            Iterator iterator = codes.iterator();
            for(int index=myvo.length; index>0; index--)
            {
             myvo[index] = ((MyEntityLocal)iterator.next()).getMyEntityLightValue();
            }
            

            *note there is no iterator.hasNext() as break condition but
            a simple counter because you know, how many times you can
            invoke iterator.next().

            For large collections you can access the item buffer of a
            collection directly without the costs of invoking a
            ArrayList.get(index) or iterator.next() at all.

            Field elementDataField = ArrayList.class.getDeclaredField("elementData");
            elementDataField.setAccessible(true);
            
            Object myEntities[] = (Object[])elementDataField.get(ahome.findAll());
            MyEntityLightValue[] myvo = new MyEntityLightValue[myEntities.length];
            
            for(int index=0; index<myvo.length; index++)
            {
             myvo[index] = ((MyEntityLocal)myEntities[index]).getMyEntityLightValue();
            }
            return myvo;
            


            or even reuse the buffer and return an array with value objects.
            (I assume the collection is garbage collected after the method call)
            Field elementDataField = ArrayList.class.getDeclaredField("elementData");
            elementDataField.setAccessible(true);
            
            Object myEntities[] = (Object[])elementDataField.get(ahome.findAll());
            
            for(int index=0; index<myEntities.length; index++)
            {
             myEntities[index] = ((MyEntityLocal)myEntities[index]).getMyEntityLightValue();
            }
            
            return myEntities; // Object[]
            


            Regards,
            Michael

            • 3. Re: Fastest way from ejbql Collection to ValueObject[]?
              semi

              Ohh... the first code block should be like this :-)

              Collection codes = ahome.findAll();
              MyEntityLightValue[] myvo = new MyEntityLightValue[codes.size()];
              Iterator iterator = codes.iterator();
              for(int index=0; index<myvo.length; index++)
              {
               myvo[index] = ((MyEntityLocal)iterator.next()).getMyEntityLightValue();
              }