0 Replies Latest reply on May 8, 2009 6:31 PM by David Paterson

    Flush-mode=manual: strange behaviour, entity is commited when changed

    David Paterson Newbie

      I am seeing strange problem with entities being committed to the database automatically even though I have the flush mode set to manual in the page.xml fragment:

      <begin-conversation join="true" flush-mode="manual"/>



      In my facelet I have the following:

      <s:decorate id="email" template="/layout/edit.xhtml">
       <ui:define name="label">Email:</ui:define>
       <h:inputText tabindex="7" validator="#{globalUserHome.validateEmail}"
           required="true" requiredMessage="Email required"
           value="#{globalUserHome.instance.email}">
         <a4j:support reRender="email" ajaxSingle="true" event="onblur"/>
        </h:inputText>
      </s:decorate>


      And validateEmail looks like this:
      public void validateEmail(FacesContext context, UIComponent toValidate, Object value) {
              log.info("validateEmail begin");
              String email (String) value;
              if (((isManaged() && !originalEmail.equals(email)) || !isManaged())) {
                  if (emailExists(email)) {
                      FacesMessage message = new FacesMessage("Email address: " + email + " already exists.");
                      context.addMessage(toValidate.getClientId(context), message);
                  }
              }
      
              if(!IDSUtil.emailValid(email)){
                  FacesMessage message = new FacesMessage("Email address: " + email + " is not valid.");
                  context.addMessage(toValidate.getClientId(context), message);
              }
      
              log.info("validateEmail end");
      }



      The entity fragement for this field is:

      @Entity
      @EntityListeners(JPAValidateListener.class)
      @Table(name = "GLOBAL_USERS", uniqueConstraints = {
              @UniqueConstraint(columnNames = "EMAIL"),
              @UniqueConstraint(columnNames = "LOGIN_NAME") })
      public class GlobalUser extends AbstractEntity implements java.io.Serializable {
      ...
      
       @Email(message="Email is in an invalid format") @NotNull
          @Column(name = "EMAIL", unique = true, nullable = false)
          public String getEmail() {
              return this.email;
          }
      
          public void setEmail(String email) {
              this.email = email;
          }
      ...
      }




      What is happening is sometimes after validateEmail is executed I am seeing an update query fire in the server log:

      12:10:28,359 INFO  [GlobalUserHome] Could not find result for email: qqqqaaa@gmail.com
      12:10:28,359 INFO  [GlobalUserHome] emailExists end
      12:10:28,359 INFO  [GlobalUserHome] validateEmail end
      12:10:28,421 INFO  [STDOUT] Hibernate: 
          update
              DPATERSON_MASTER1.GLOBAL_USERS 
          set
              EMAIL=?,
              LAST_MODIFIED=?,
              LOGIN_NAME=?,
              POD_ID=? 
          where
              GLOBAL_USERS_ID=?



      This does not happen all the time, about 50% of the time validateEmail fires and the entity is left in a dirty state as it should be because of flushMode=MANUAL.


      Has anyone else seen this kind of behavior or have any tips as to how I can debug it?  Seam is a bit of a black box here and it's difficult to see exactly what's going on.  I don't want any changes to the database until the user executes an action to commit the entity.  Especially in this case, the validation may fail, finding a duplicate email address, but the entity is still commited causing a constraint violation error on commit, very bad. I am using Seam 2.0.3.CR1.