Spring-MVC's @Valid is throwing form errors that do not exist
I have a weird problem in that I am trying to edit an existing Company object through a Spring MVC Controller that has a few Validation rules on it. The validation is getting triggered using @Valid.
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(@Valid Company company, BindingResult result, SessionStatus status) {
if(result.hasErrors()) {
return view("edit");
} else {
companyService.saveCompany(company);
status.setComplete();
return redirect("?isSaved=true");
}
}
The individual validations on the Company object pass in unit tests. When used in other parts of the application, they work fine. However, for one of the forms, Spring always throws errors like "Field should not be empty" or "the phone number format is wrong", but the data is actually correct.
The worst thing about this situation is that this code has been in play for over a year - it is just a simple "Edit your company info" screen. It has suddenly just stopped working. Regardless of what I submit on the form, Spring will throw these errors.
I have checked and double-checked everything that could be going wrong. It is loading the correct Company object. It is also posting the correct values too. As a sanity check, I even display the exact error objects after I submit the form:
Field error in object 'company' on field 'phoneNumber': rejected value [451-324-3232]; codes [Pattern.company.phoneNumber,Pattern.phoneNumber,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [company.phoneNumber,phoneNumber]; arguments []; default message [phoneNumber],[Ljavax.validation.constraints.Pattern$Flag;@2c99f9,(\()?(\d){3}(\))?(\s|-)(\d){3}(\s|-)(\d){4}]; default message [Must be of the form: ###-###-####]
Field error in object 'company' on field 'name': rejected value [somewhere]; codes [NotEmpty.company.name,NotEmpty.name,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [company.name,name]; arguments []; default message [name]]; default message [Name may not be empty]
Field error in object 'company' on field 'address.address': rejected value [135431]; codes [NotEmpty.company.address.address,NotEmpty.address.address,NotEmpty.address,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework开发者_Go百科.context.support.DefaultMessageSourceResolvable: codes [company.address.address,address.address]; arguments []; default message [address.address]]; default message [Address may not be empty]
As you can see, the values are correct, but it's throwing the errors anyway.
Also, the company object has an ID - it's not getting lost or anything like that.
If I remove @Valid, everything works. All the values get changed, so I know it's something directly related to @Valid. But what?
I know you might be thinking that the validation rules must be wrong or something... but they aren't. How can someone mess up @NotEmpty constraints?
public class Company extends DomainObject {
@NotEmpty(message = "{company.name.notEmpty}")
private String name;
@Valid
private Address address = new Address();
@Pattern(message = "{company.phoneNumber.valid}",
regexp = "(\\()?(\\d){3}(\\))?(\\s|-)(\\d){3}(\\s|-)(\\d){4}")
private String phoneNumber = "";
private boolean isEnabled = true;
private boolean homepageViewable = true;
private int coursesCreated = 0;
@Valid
private Theme theme = new Theme();
It doesn't matter what I put into these fields - I still get the errors. Also, when testing these validations in isolation, THEY WORK. In fact, when @Valid is used for the Company object in other parts of the system (like a Registration sign-up form), it works too.
So the only part where it does not work is the Company Profile screens.
Is there any reason why Spring-MVC would do this? I am totally at a loss. I don't even know what the heck I did to cause this problem. It's not like any unit/integration tests have failed as I was making changes. I was never alerted that this was a problem until I manually tried these screens - a common annoyance when using Spring/Java because there are many cases where unit/integration tests are slightly different than using a real production container, so problems slip by anyway.
Please help.
One thought. When company validation works, is it always on a form where the company is part of something bigger? E.g., with registration, the company is part of a registration. But when you try to save the company on a company form, it fails...
Can you try attaching @ModelAttribute to the Company arg? I.e.
@ModelAttribute @Valid Company company
Does it help?
精彩评论