Weird problem with Spring MVC, Bean Validation using @Valid and Hibernate

I have an application uses bean validation in 50 domain classes. It has worked for months without any problems using @Valid in the Spring MVC controllers.

Now all of a sudden, I have made many fields "lazy" in Hibernate to improve performance. I have had to deal with all sorts of weird issues, from equals() method no longer working, to objects being in the session crashing because the data wasn't loaded.

I have come across a very weird problem now where I am loading the data into a session attribute on a Spring MVC form, the view renders it properly, but when passed to @Valid, it reports ALL of the fields to have errors even though the data is 100% valid.

public class EducationFacility extends DomainObject {

    /* Members */
    @NotEmpty(message = "{educationFacility.name.notEmpty}")
    private String name;

    @Valid
    private Address address = new Address();

    @Pattern(message = "{educationFacility.phoneNumber.valid}",
        regexp = "(\\()?(\\d){3}(\\))?(\\s|-)(\\d){3}(\\s|-)(\\d){4}")
    private String phoneNumber = "";
    ...
}

Here's the hibernate definition:

<class name="jobprep.domain.educationfacility.EducationFacility" table="education_facility">
    <id name="id" column="education_facility_id" type="long">
        <generator class="native" />
    </id>
    <property name="name" column="name"/>
    <component name="address" class="jobprep.domain.educationfacility.Address">
        <property name="address" column="address"/>
        <property name="postalCode" column="postal_code"/>
        <many-to-one name="province" class="jobprep.domain.educationfacility.Province" column="province_id"  />
    </component>
    <property name="phoneNumber" column="phone_number"/>
    <property name="isEnabled" column="is_enabled"/>
    <property name="homepageViewable" column="homepage_viewable" />
    <property name="coursesCreated" />
    <many-to-one name="admin" class="jobprep.domain.user.Admin" column="admin_id" />
    <many-to-one name="director" class="jobprep.domain.educationfacility.Director"
                 column="director_id" cascade="all" />
    <bag name="teachers" inverse="true" cascade="all-delete-orphan" order-by="username asc">
        <key column="education_facility_id" />
        <one-to-many class="jobprep.domain.teacher.Teacher" />
    </bag>
    <bag name="students" inverse="true" cascade="all-delete-orphan" order-by="username asc">
        <key column="student_education_facility_id" />
        <one-to-many class="jobprep.domain.student.Student"/>
    </bag>
    <bag name="ipRestrictions" inverse="true" cascade="all-delete-orphan">
        <key column="education_facility_id" />
        <one-to-many class="jobprep.domain.educationfacility.IpRestriction" />
    </bag>
    <bag name="allowedModules" table="education_facility_to_module"
         inverse="false" lazy="true">
        <key column="education_facility_id" />
        <many-to-many class="jobprep.domain.module.Module" column="module_id"/>
    </bag>
</class>

Here's the controller definition:

@Controller
@RequestMapping("/myEducationFacility")
@SessionAttributes("educationFacility")
@PreAuthorize("hasRole('ROLE_DIRECTOR')")
public class MyEducationFacilityController extends ControllerSupport {
    ....
}

Here's the MVC's save method:

    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(@Valid EducationFacility educationFacility, BindingResult result, SessionStatus status) {
        if(result.hasErrors()) {
            return view("index");
        } else {
            adminService.saveEducationFacility(educationFacility);
            status.setComplete();

            return redirect("?complete=true");
        }
    }

Here's the errors Spring is Added to the binding result when save() is invoked by Spring. These are totally wrong:

{org.springframework.validation.BindingResult.educationFacility=org.springframework.validation.BeanPropertyBindingResult: 4 errors
    Field error in object 'educationFacility' on field 'phoneNumber': rejected value [(519) 254-3678]; codes [Pattern.educationFacility.phoneNumber,Pattern.phoneNumber,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [educationFacility.phoneNumber,phoneNumber]; arguments []; default message [phoneNumber],[Ljavax.validation.constraints.Pattern$Flag;@29895454,(\()?(\d){3}(\))?(\s|-)(\d){3}(\s|-)(\d){4}]; default message [Must be of the form: ###-###-####]
    Field error in object 'educationFacility' on field 'address.address': rejected value [Windsor]; codes [NotEmpty.educationFacility.address.address,NotEmpty.address.address,NotEmpty.address,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [educationFacility.address.address,address.address]; arguments []; default message [address.address]]; default message [Address may not be empty]
    Field error in object 'educationFacility' on field 'name': rejected value [Catholic School Board]; codes [NotEmpty.educationFacility.name,NotEmpty.name,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [educationFacility.name,name]; arguments []; default message [name]]; default message [Name may not be empty]
    Field error in object 'educationFacility' on field 'address.postalCode': rejected value [N9a 2a5]; codes [Pattern.educationFacility.address.postalCode,Pattern.address.postalCode,Pattern.postalCode,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [educationFacility.address.postalCode,address.postalCode]; arguments []; default message [address.postalCode],[Ljavax.validation.constraints.Pattern$Flag;@29895454,[a-zA-Z]\d[a-zA-Z](\s|-)\d[a-zA-Z]\d]; default message [Postal Code must be of the format: a#a-#a#], educationFacility=class jobprep.domain.educationfacility.EducationFacility{id=3}}

Help?

Answers


Just a guess, but try to set contraint annotations on getters instead of fields. Perhaps state of the fields doesn't match values returned by getters due to some lazy-loading magic.


Need Your Help

Put multiple textboxes and labels under each other on the same column css?

c# asp.net css layout

Hello! Is it possible to put multiple textboxes and labels under each other on the same column as shown in the picture by CSS coding? and how? when i do it, it appears like this : ...

Android webview appears white for a moment

android android-webview

I'm using a webview on my activity. page is loaded from android_asset:

Generate large prime number with specified last digits

c# java algorithm primes

Was wondering how is it possible to generate 512 bit (155 decimal digits) prime number, last five decimal digits of which are specified/fixed (eg. ***28071) ??

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.