1 Reply Latest reply on Oct 28, 2004 9:09 AM by jamesstrachan

    Why an ejbLoad() call for each get* method?

    ricardovm

      I'm writing an entity bean called from a session bean. For tests only, I do:

      ctx.getUserTransaction().begin();
      TestLocal t = home.findByPrimaryKey(id);

      String str_field = t.getStringField();
      Integer int_field = t.getIntegerField();

      t.setStringField("New Value");
      t.setIntegerField(new Integer(123));

      ctx.getUserTransaction().commit();

      And I see in the logs two calls to ejbLoad() and one to ejbStore().

      In my application, I need to do 70 get* calls (for different table fields), and these calls to ejbLoad() are slowing my application.

      Can anyone help me?

        • 1. Re: Why an ejbLoad() call for each get* method?
          jamesstrachan


          This is one that comes up regularly, and there are several areas that you need to check.

          The fact that you are getting two ejbLoad() calls and one ejbStore() call suggests that the entity bean may not be taking part in the transaction that you have declared. Check in the deployment descriptor that the method calls are marked as Supports or Required.

          <assembly-descriptor>
           <container-transaction>
           <method>
           <ejbName>mySessionBean</ejb-name>
           <method-name>*</method-name>
           <ejbName>myEntityBean</ejb-name>
           <method-name>*</method-name>
           </method>
           <trans-attribute>Required</trans-attribute>
           </container-transaction>
          </assembly-descriptor>
          

          In fact, if you use the Required attribute on your session bean, you won't need to do explicit transaction management at all.

          Secondly, you may need to look at the commit-option element in your JBoss configuration file. If you have exclusive use of the database, you can set this to commit option "A" which will minimise reloads outside a transaction. The server will still reload once at the start of a transaction.

          Third, and most valuable, you can write a Value Object that gets all fields in one method call. For your small scale example, the class looks like :-

          public Class MyTinyValueObject {
          
           private String strField;
           private int intField;
          
           myTinyValueObject() {}
          
           public int getIntField() {
           return intField;
           }
          
           public void setIntField(int newInt) {
           this.intField = newInt;
           }
          
           // Getter and setter repeated for strField.
          
          }
          

          This can then be called from your session bean as shown below :-
           TestLocal t = home.findByPrimaryKey(id);
          
           MyTinyValueObject mtvo = t.getValueObject();
           String str_field = mtvo.getStrField();
           int int_field = mtvo.getIntegerField();
          
           mtvo.setStrField("New Value");
           mtvo.setIntField(123);
           t.setValueObject( mtvo );
          

          This reduces your potentially 70 gets to 1, will improve performance and minimise the opportunities for the server to call ejbLoad().

          It sounds as though the session bean and entity bean are in the same memory space in the server. Minimising the number of method calls is even more important if there is also network I/O involved.

          James