1 Reply Latest reply on Apr 28, 2005 6:35 AM by dlmiles

    ejbCreate causes pointless UPDATE to be executed

    drpacman

      I am experiencing some very strange behaviour with Jboss 3.2.3, mysql 4 using code generated using ejbdoclet. After each call to ejbCreate I can see from the database logs that all fields which have setter methods on the entity bean are updated to the database (despite not being changed).
      Why is the update occurring and what is the configuration option to ensure only true "updates" cause an update to run?

      For the following class a call to ejbCreate causes the following entries in mysql log:
      SET autocommit=0
      15 Query INSERT INTO generic_user_credits (opening_portal_eventId, carrierId, userId, credits, productId, billing_productId, start_date, end_date, recredit) VALUES ('bundlecredit1', 'staging', 'userA', 100, 'TestBundle', 'sub1', '2005-04-26 17:15:53', '2005-04-27 17:15:53', 0)
      15 Query UPDATE generic_user_credits SET start_date='2005-04-26 17:15:53', end_date='2005-04-27 17:15:53' WHERE id=58
      15 Query commit


      The sample code is:
      /**
      * This is the generic credit entity bean.
      * It represents a set of credits which were bought at a single instance. Credits should only go down, not up.
      * If a new set a credits need to be added a new bean should be created
      *
      * @ejb.bean
      * name="GenericCredit"
      * type="CMP"
      * jndi-name="GenericCredit"
      * primkey-field="id"
      * cmp-version=2.x
      *
      * @ejb.pk class = "java.lang.Integer"
      * @jboss.entity-command name="mysql-get-generated-keys"
      *
      * @ejb.home
      * remote-class="genericcredits.interfaces.GenericCreditHome"
      * local-class="genericcredits.interfaces.GenericCreditLocalHome"
      *
      * @ejb.interface
      * remote-class="genericcredits.interfaces.GenericCredit"
      * local-class="genericcredits.interfaces.GenericCreditLocal"
      *
      * @ejb.finder
      * signature="java.util.Collection findAll()"
      *
      * @ejb.transaction
      * type="Required"
      *
      * @ejb.value-object
      * name="GenericCredit"
      * match="credit"
      *
      * @jboss.create-table "false"
      * @jboss.remove-table "false"
      * @jboss.read-only "false"
      * @jboss.datasource "java:/users"
      * @jboss.table-name "generic_user_credits"
      *
      * @version 1.0
      */

      public abstract class GenericCreditBean implements EntityBean {

      private static final Date NEVER_EXPIRE_DATE = (new GregorianCalendar(2999, 11, 31)).getTime();

      /**
      * Constructor for the GenericCreditBean object
      */
      public GenericCreditBean() { }


      /**
      * @ejb.pk-field
      * @ejb.interface-method
      * @ejb:persistent-field
      * @ejb.persistence column-name="id" sql-type="INT"
      * @jboss.sql-type integer
      * @jboss:persistence auto-increment="true"
      * @ejb.value-object match="credit"
      */
      public abstract Integer getId();
      public abstract void setId(Integer id);

      /**
      * @ejb.interface-method
      * @ejb:persistent-field
      * @ejb.persistence column-name="opening_portal_eventId" sql-type="VARCHAR"
      * @jboss.sql-type VARCHAR(50)
      * @ejb.value-object match="credit"
      */
      public abstract String getOpeningEventId();
      public abstract void setOpeningEventId(String eventId);

      /**
      * @ejb.interface-method
      * @ejb:persistent-field
      * @ejb.persistence column-name="carrierId" sql-type="VARCHAR"
      * @jboss.sql-type VARCHAR(50)
      * @ejb.value-object match="credit"
      */
      public abstract String getCarrierId();
      public abstract void setCarrierId(String eventId);

      /**
      * @ejb.interface-method
      * @ejb:persistent-field
      * @ejb.persistence column-name="userId" sql-type="VARCHAR"
      * @jboss.sql-type VARCHAR(50)
      * @ejb.value-object match="credit"
      */
      public abstract String getUserId();
      public abstract void setUserId(String userId);


      /**
      * @ejb.interface-method
      * @ejb:persistent-field
      * @ejb.persistence column-name="credits" sql-type="INT"
      * @jboss.sql-type INT
      * @jboss.persistence.not-null="true"
      * @ejb.value-object match="credit"
      */
      public abstract int getCredits();
      /**
      * @ejb.interface-method view-type="both"
      */
      public abstract void setCredits(int credits);

      /**
      * Indicate the product which caused the credits may be spent against - null indicates it is unrestricted
      * @ejb.interface-method
      * @ejb:persistent-field
      * @ejb.persistence column-name="productId" sql-type="VARCHAR"
      * @jboss.sql-type VARCHAR(50)
      * @ejb.value-object match="credit"
      */
      public abstract String getProductId();
      public abstract void setProductId(String productId);

      /**
      * Indicate the products which caused the credits to be added
      * @ejb.interface-method
      * @ejb:persistent-field
      * @ejb.persistence column-name="billing_productId" sql-type="VARCHAR"
      * @jboss.sql-type VARCHAR(50)
      * @ejb.value-object match="credit"
      */
      public abstract String getBillingProductId();
      public abstract void setBillingProductId(String billingProductId);

      /**
      * @ejb.interface-method view-type="both"
      * @ejb:persistent-field
      * @ejb.persistence
      * column-name="start_date"
      * sql-type="TIMESTAMP"
      * jdbc-type="TIMESTAMP"
      * @ejb.value-object match="credit"
      */
      public abstract Date getStartDate();
      /**
      * @ejb.interface-method view-type="both"
      */
      public abstract void setStartDate(Date startDate);


      /**
      * @ejb.interface-method view-type="both"
      * @ejb:persistent-field
      * @ejb.persistence
      * column-name="end_date"
      * sql-type="TIMESTAMP"
      * jdbc-type="TIMESTAMP"
      * @ejb.value-object match="credit"
      */
      public abstract Date getEndDate();
      /**
      * @ejb.interface-method view-type="both"
      */
      public abstract void setEndDate(Date endDate);


      /**
      * @ejb:persistent-field
      * @ejb.persistence
      * column-name="recredit"
      * jdbc-type="INT"
      * @ejb.value-object match="credit"
      */
      public abstract int getRecredit();
      public abstract void setRecredit(int recredit);

      /**
      * @ejb.interface-method view-type="both"
      */
      public abstract com.mforma.mserver.services.genericcredits.dao.GenericCreditValue getGenericCreditValue();


      /**
      * Create GenericCredit entry.
      *
      * @ejb.create-method
      */
      public Integer ejbCreate(String carrierId, String userId, String billingProductId, String productId, int credits, Date startDate, Date endDate, String openingPortalEventId, boolean isRecredit) throws javax.ejb.CreateException {

      setCarrierId(carrierId);
      setUserId(userId);
      setBillingProductId(billingProductId);
      setProductId(productId);
      setCredits(credits);
      setStartDate(startDate);
      setEndDate(endDate == null ? NEVER_EXPIRE_DATE : endDate );
      setOpeningEventId(openingPortalEventId);
      setRecredit(isRecredit ? 1 : 0);

      return getId();
      }


      Thanks for any insight into why this is happening

      Paul

        • 1. Re: ejbCreate causes pointless UPDATE to be executed
          dlmiles

          I dont really know but...

          Are you really sure TIMESTAMP is the SQL type you want and not DATETIME. TIMESTAMP has sub-second resolution and DATETIME second resolution. It might be possible that Java is tracking sub-seconds and therefore sees these columns as needing updating. The data might not be expressed as subseconds because java.lang.Date only has second resolution too, but that might not stop CMP tracking the fact and marking the object fields dirty.

          I believe there to be other magic properties of the SQL type TIMESTAMP that simply dont apply to DATETIME.