Flush-mode=manual: strange behaviour, entity is commited when changed
dpaterson.dpaterson.convexsolutions.com May 8, 2009 6:31 PMI 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.