Ok, when i changed order from validation="required,email" to validation="email,required" email validation starts to work properly. Looks like some magic :). However, I get sometimes user data lost. I can't reproduce this bug with 100% probability, but it occurs sometimes. I tried also to change @Persist(PersistenceConstants.FLASH) to default @Persist. But it gives me behavior I don't want - it renders user data even if I refresh the page (I want to show blank form in that case). So FLASH persistance is what I want, but sometimes data are lost.
My code now looks like this: -------------------Registration.java----------------------------------------- public class Registration { @Property @Persist(PersistenceConstants.FLASH) private User user; @Property @Persist(PersistenceConstants.FLASH) private Customer customer; @Property private String verifyPassword; @Inject private CustomerService customerService; @Inject private UserService userService; @Component private Form registerForm; @Inject private Messages messages; @OnEvent(value = EventConstants.SUCCESS, component = "registerForm") Object validateAndSave() { if (errorsDetected()){ return null; } user.setPassword(generateHash(user.getPassword())); customer.addUser(user); customerService.save(customer); // redirect with a message parameter return Index.class; } private boolean errorsDetected(){ boolean errorDetected = false; if (!verifyPassword.equals(user.getPassword())) { registerForm.recordError(verifyPassword, messages.get("error.verify.password")); errorDetected = true; } if (userService.getUserByLogin(user.getLogin()) != null) { registerForm.recordError(messages.get("error.user.already.exists")); errorDetected = true; } if (customerService.getCustomerByBusinessName(customer.getBusinessName()) != null) { registerForm.recordError(messages.get("error.customer.already.exists")); errorDetected = true; } return errorDetected; } } -------------Registration.tml---------------------------------------------------------------- <html t:type="layout" title="Customer registration" t:sidebarTitle="Current Time" t:pageTitle="Register" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> <fieldset id="register"> <form class="full-form" t:id="registerForm"> <t:errors/> <fieldset> <legend>Customer registration (company or private person)</legend> <t:beaneditor object="customer" exclude="literal:id,users"> <p:businessName> <t:label for="businessName"/> <t:textfield t:id="businessName" value="customer.businessName" validate="required"/> </p:businessName> <p:contactPhone> <t:label for="customer_contactPhone"/> <t:textfield t:id="customer_contactPhone" value="customer.contactPhone" validate="required"/> </p:contactPhone> <p:contactPerson> <t:label for="contactPerson"/> <t:textfield t:id="contactPerson" value="customer.contactPerson" validate="required"/> </p:contactPerson> <p:businessAddress> <t:label for="businessAddress"/> <t:textfield t:id="businessAddress" value="customer.businessAddress" validate="required"/> </p:businessAddress> <p:email> <t:label for="customer_email"/> <t:textfield t:id="customer_email" value="customer.email" validate="email,required"/> </p:email> </t:beaneditor> </fieldset> <fieldset> <legend>Personal registration</legend> <t:beaneditor object="user" exclude="literal:id,roles" add="verifyPassword"> <p:firstName> <t:label for="firstName"/> <t:textfield t:id="firstName" value="user.firstName" validate="required"/> </p:firstName> <p:middleName> <t:label for="middleName"/> <t:textfield t:id="middleName" value="user.middleName" validate="required"/> </p:middleName> <p:lastName> <t:label for="lastName"/> <t:textfield t:id="lastName" value="user.lastName" validate="required"/> </p:lastName> <p:contactPhone> <t:label for="contactPhone"/> <t:textfield t:id="contactPhone" value="user.contactPhone" validate="required"/> </p:contactPhone> <p:mobilePhone> <t:label for="mobilePhone"/> <t:textfield t:id="mobilePhone" value="user.mobilePhone" validate="required"/> </p:mobilePhone> <p:address> <t:label for="address"/> <t:textfield t:id="address" value="user.address" validate="required"/> </p:address> <p:email> <t:label for="email"/> <t:textfield t:id="email" value="user.email" validate="required"/> </p:email> <p:nickname> <t:label for="nickname"/> <t:textfield t:id="nickname" value="user.nickname" validate="required"/> </p:nickname> <p:login> <t:label for="login"/> <t:textfield t:id="login" value="user.login" validate="required"/> </p:login> <p:password> <t:label for="password"/> <t:passwordfield t:id="password" value="user.password" validate="required"/> </p:password> <p:verifyPassword> <t:label for="verifyPassword"/> <t:passwordfield t:id="verifyPassword" value="verifyPassword" validate="required"/> </p:verifyPassword> </t:beaneditor> </fieldset> <div class="form-submit"> <input type="submit" value="Register"/> </div> <div class="member">Already a member? <t:pagelink page="Login">Login now!</t:pagelink> </div> </form> </fieldset> </html> 2010/10/25 Mark <mark-li...@xeric.net> > So if there is another problem the email validation will show you an error, > but not if the email validation is the only issue? That seems very odd. > You might try switching the order from validation="required,email" to > validation="email,required" just to see what happens. > > Mark > > On Mon, Oct 25, 2010 at 10:24 AM, Anton Mezerny <anton.meze...@gmail.com > >wrote: > > > Required validation works on client side, so I have not tested it on > > server. > > I can say, that when my custom validation causes error (password and > > password verification don't match), then I have 2 error messages on > > registration page (if email is also not valid) - email error and password > > verification error. > > > > Anton > > > > 2010/10/25 Mark <mark-li...@xeric.net> > > > > > Do all the other validations perform as expected other than email? Does > > the > > > "required" validation on email work correctly and give you an error > when > > > you > > > try to submit. Also do you have any types of constraints on the email > > field > > > in the database? Is it possible that what you are entering in the email > > > fields is passing the email validation, but getting rejected by the > > > database? > > > > > > I don't remember what Tapestry uses to determine whether or not > something > > > is > > > a valid email address, but I do know that the actual spec for email > > > addresses is a lot more permissive than you'd think. > > > > > > Mark > > > > > > On Mon, Oct 25, 2010 at 6:35 AM, Anton Mezerny < > anton.meze...@gmail.com > > > >wrote: > > > > > > > So, I removed initializeNewUser() from Registration.java and added > > > @Inject > > > > annotation to User.java and Customer.java (I also made user and > > customer > > > > separate, not nested one into another and I nest user into customer > > just > > > > before saving to DB). Now page renders well, but when I try to save > > user > > > > and > > > > customer (and email is invalid) - email validation does not occurs - > I > > > just > > > > have email = null in my customer.email field (even if i set some > > > incorrect > > > > value, for exapmle 'test_email'). There is no redirect to the > > > registration > > > > page with error message - program continues execution and tries to > save > > > > data > > > > to DB. > > > > > > > > 2010/10/23 Mark W. Shead <mwsh...@gmail.com> > > > > > > > > > I don't think you want to use flash persistence for this. Try just > > > > > using @Persist. It looks like you are creating a new user every > time > > > > > the page renders. > > > > > > > > > > Mark > > > > > > > > > > On Sat, Oct 23, 2010 at 3:08 PM, Jim O'Callaghan < > > > jc1000...@yahoo.co.uk> > > > > > wrote: > > > > > > I'm not sure if this is relevant to your current problem, but to > > tell > > > > > > Tapestry which constructor to use for the bean editor, you should > > > > > annotate > > > > > > the default (no args) constructor with @Inject - this will allow > > the > > > > BEF > > > > > to > > > > > > create the relevant entity if none if present. Hope this helps. > > > > > > > > > > > > Regards, > > > > > > Jim. > > > > > > > > > > > > -----Original Message----- > > > > > > From: Anton Mezerny [mailto:anton.meze...@gmail.com] > > > > > > Sent: 23 October 2010 17:02 > > > > > > To: Tapestry users > > > > > > Subject: Objects session persistance and validation > > > > > > > > > > > > Hi all, > > > > > > I'm trying to write simple registration form using beaneditor > > > > component. > > > > > > If I fullfill all reqired fields in the form and submit it - > > > everything > > > > > > works fine, but if server validation occurs (for example > passwords > > > > don't > > > > > > match), then all data is lost and Registration page renders with > > > > > validation > > > > > > errors, but without user data (input values). > > > > > > I think the reason for this behaviour is the initializeNewUser() > > > > method, > > > > > > wich rewrites all data if user field is null. But if I delete > this > > > > method > > > > > > from code, tapestry throws exception - User can't be instantiated > > > > > (tapestry > > > > > > tries to use constructor with most parameters, which has custom > > > > objects, > > > > > not > > > > > > only String, Integer, etc). So how can resolve this problem? > > > > > > Thanks in advance. > > > > > > > > > > > > My code (some code is token from Tapestry5 Hotel Booking > example): > > > > > > > > > > > > > > > > > > > > > -----------------Registration.java:----------------------------------------- > > > > > > --- > > > > > > > > > > > > public class Registration { > > > > > > > > > > > > @Property > > > > > > @Persist(PersistenceConstants.FLASH) > > > > > > private User user; > > > > > > > > > > > > @OnEvent(value = EventConstants.PREPARE, component = > > > "registerForm") > > > > > > private void initializeNewUser() { > > > > > > if (this.user == null) { > > > > > > this.user = new User(); > > > > > > this.user.setCustomer(new Customer()); > > > > > > } else { > > > > > > if (this.user.getCustomer() == null) { > > > > > > this.user.setCustomer(new Customer()); > > > > > > } > > > > > > } > > > > > > } > > > > > > > > > > > > > > > > > > @Property > > > > > > private String verifyPassword; > > > > > > > > > > > > @Inject > > > > > > private UserService userService; > > > > > > > > > > > > @Component > > > > > > private Form registerForm; > > > > > > > > > > > > @Inject > > > > > > private Messages messages; > > > > > > > > > > > > public Object onSubmitFromRegisterForm() { > > > > > > > > > > > > if (!verifyPassword.equals(user.getPassword())) { > > > > > > > > > > > registerForm.recordError(messages.get("error.verify.password")); > > > > > > > > > > > > return null; > > > > > > } > > > > > > > > > > > > if (userService.getUserByLogin(user.getLogin()) != null) { > > > > > > > > > > > > > > registerForm.recordError(messages.get("error.user.already.exists")); > > > > > > > > > > > > return null; > > > > > > } > > > > > > > > > > > > userService.save(user); > > > > > > > > > > > > return Index.class; > > > > > > > > > > > > } > > > > > > } > > > > > > > > > > > > > > > > > > > --------------Registration.tml------------------------------------ > > > > > > > > > > > > > > > > > > <html t:type="layout" title="Customer registration" > > > > > > t:sidebarTitle="Current Time" > > > > > > t:pageTitle="Register" > > > > > > xmlns:t=" > http://tapestry.apache.org/schema/tapestry_5_1_0.xsd > > " > > > > > > xmlns:p="tapestry:parameter"> > > > > > > > > > > > > <fieldset id="register"> > > > > > > <form class="full-form" t:id="registerForm"> > > > > > > <t:errors/> > > > > > > > > > > > > <fieldset> > > > > > > <legend>Customer registration(company or > private > > > > > > person)</legend> > > > > > > > > > > > > <t:beaneditor object="user.customer" > > > > > > exclude="literal:id,users"> > > > > > > <p:businessName> > > > > > > <t:label for="businessName"/> > > > > > > <t:textfield t:id="businessName" > > > > > > value="user.customer.businessName" validate="required"/> > > > > > > </p:businessName> > > > > > > <p:contactPhone> > > > > > > <t:label for="customer_contactPhone"/> > > > > > > <t:textfield > > t:id="customer_contactPhone" > > > > > > value="user.customer.contactPhone" validate="required"/> > > > > > > </p:contactPhone> > > > > > > <p:contactPerson> > > > > > > <t:label for="contactPerson"/> > > > > > > <t:textfield t:id="contactPerson" > > > > > > value="user.customer.contactPerson" validate="required"/> > > > > > > </p:contactPerson> > > > > > > <p:businessAddress> > > > > > > <t:label for="businessAddress"/> > > > > > > <t:textfield t:id="businessAddress" > > > > > > value="user.customer.businessAddress" validate="required"/> > > > > > > </p:businessAddress> > > > > > > <p:email> > > > > > > <t:label for="customer_email"/> > > > > > > <t:textfield t:id="customer_email" > > > > > > value="user.customer.email" validate="required,email"/> > > > > > > </p:email> > > > > > > </t:beaneditor> > > > > > > </fieldset> > > > > > > > > > > > > <fieldset> > > > > > > <legend>Personal registration</legend> > > > > > > <t:beaneditor object="user" exclude="literal:id,roles" > > > > > > add="verifyPassword"> > > > > > > > > > > > > > > > > > > <p:firstName> > > > > > > <t:label for="firstName"/> > > > > > > <t:textfield t:id="firstName" > > > value="user.firstName" > > > > > > validate="required"/> > > > > > > </p:firstName> > > > > > > > > > > > > > > > > > > <p:middleName> > > > > > > <t:label for="middleName"/> > > > > > > <t:textfield t:id="middleName" > > > > value="user.middleName" > > > > > > validate="required"/> > > > > > > </p:middleName> > > > > > > > > > > > > > > > > > > <p:lastName> > > > > > > <t:label for="lastName"/> > > > > > > <t:textfield t:id="lastName" > > value="user.lastName" > > > > > > validate="required"/> > > > > > > </p:lastName> > > > > > > > > > > > > > > > > > > <p:contactPhone> > > > > > > <t:label for="contactPhone"/> > > > > > > <t:textfield t:id="contactPhone" > > > > > > value="user.contactPhone" validate="required"/> > > > > > > </p:contactPhone> > > > > > > > > > > > > > > > > > > <p:mobilePhone> > > > > > > <t:label for="mobilePhone"/> > > > > > > <t:textfield t:id="mobilePhone" > > > > > value="user.mobilePhone" > > > > > > validate="required"/> > > > > > > </p:mobilePhone> > > > > > > > > > > > > > > > > > > <p:address> > > > > > > <t:label for="address"/> > > > > > > <t:textfield t:id="address" > value="user.address" > > > > > > validate="required"/> > > > > > > </p:address> > > > > > > > > > > > > > > > > > > <p:email> > > > > > > <t:label for="email"/> > > > > > > <t:textfield t:id="email" value="user.email" > > > > > > validate="required"/> > > > > > > </p:email> > > > > > > > > > > > > > > > > > > <p:nickname> > > > > > > <t:label for="nickname"/> > > > > > > <t:textfield t:id="nickname" > > value="user.nickname" > > > > > > validate="required"/> > > > > > > </p:nickname> > > > > > > > > > > > > > > > > > > <p:login> > > > > > > <t:label for="login"/> > > > > > > <t:textfield t:id="login" value="user.login" > > > > > > validate="required"/> > > > > > > </p:login> > > > > > > > > > > > > > > > > > > <p:password> > > > > > > <t:label for="password"/> > > > > > > <t:passwordfield t:id="password" > > > > value="user.password" > > > > > > validate="required"/> > > > > > > </p:password> > > > > > > > > > > > > <p:verifyPassword> > > > > > > <t:label for="verifyPassword"/> > > > > > > <t:passwordfield t:id="verifyPassword" > > > > > > value="verifyPassword" validate="required"/> > > > > > > </p:verifyPassword> > > > > > > > > > > > > </t:beaneditor> > > > > > > > > > > > > </fieldset> > > > > > > > > > > > > <div class="form-submit"> > > > > > > <input type="submit" value="Register"/> > > > > > > </div> > > > > > > <div class="member">Already member? > > > > > > <t:pagelink page="Login">Login now!</t:pagelink> > > > > > > </div> > > > > > > </form> > > > > > > </fieldset> > > > > > > </html> > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > > > > > > For additional commands, e-mail: users-h...@tapestry.apache.org > > > > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > > > > > For additional commands, e-mail: users-h...@tapestry.apache.org > > > > > > > > > > > > > > > > > > > >