Nuñito Calzada
Nuñito Calzada

Reputation: 2076

BindingResult not working in Spring 3.2.8 using JSR-303 BEAN VALIDATION

I am working in Validation, Data Binding, and Type Conversion in Spring 3.2.8...

I have this controller

@Controller
public class SaveAccountController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/accounts/saveaccount.do", method = RequestMethod.POST)
private String saveAccount  (   @Valid @ModelAttribute("dataAccountCommand") final DataAccountCommand dataAccountCommand, 
                                BindingResult result) {

        return "registerAccountView";

    }               
}

this java object:

public class DataAccountCommand {

    @Valid  
    User userBean;

    public User getUserBean() {
        return userBean;
    }

    public void setUserBean(User userBean) {
        this.userBean = userBean;
    }

    @Override
    public String toString() {
        return "DataAccountCommand [userBean=" + userBean + "]";
    }       
}

and this other one:

  @SuppressWarnings("serial")
    @Entity
    @Table(name = "T_USER", uniqueConstraints = { @UniqueConstraint(columnNames = "LOGIN"), @UniqueConstraint(columnNames = "EMAIL") })
    @SequenceGenerator(name = "seqUSER", sequenceName = "SEQ_USER")
    public class User implements java.io.Serializable {

        @Id
        @Column(name = "ID", unique = true, nullable = false, precision = 38, scale = 0)
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqUSER")
        private Long id;

        @Column(name = "ROLE", nullable = false, precision = 38, scale = 0)
        @Enumerated(EnumType.ORDINAL)
        protected UserRole userRole;

        @ManyToOne(fetch = FetchType.EAGER) 
        @JoinColumn(name = "COMPANY")
        private Company company;

        @Column(name = "POSITION")
        @NotNull
        @Size(min=10)
        private String position;
    ....
}

and this in the applicationContext.xml

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

and here my servlet:

<!-- Maps incoming URLs to classnames -->

<bean name="controllerHandler" class="springext.web.servlet.mvc.support.ControllerClassNameHandlerMapping">        
    <property name="basePackage" value="fr.telecom.controller" />
    <property name="interceptors">
        <list>
            <!-- Checks a specific request parameter if the locale is changed. -->
            <ref bean="localeChangeInterceptor"/>
            <ref bean="sessionInterceptor"/>
        </list>
    </property>
</bean>

<!-- Action URL mappings to controllers. -->
<bean id="handlerMapping"
    class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
    <property name="interceptors">
        <list>
            <!-- Checks a specific request parameter if the locale is changed. -->
            <ref bean="localeChangeInterceptor"/>
            <ref bean="sessionInterceptor"/>
        </list>
    </property>
</bean>

in the controller position is empty, but result.hasErrors() is false !!!!!

I've tried also using another approach:

@Controller
public class SaveAccountController {

    @Autowired
    private UserService userService;

    @Autowired
    LocalValidatorFactoryBean validator;


    @RequestMapping(value = "/accounts/saveaccount.do", method = RequestMethod.POST)
    private String saveAccount  (   @Valid @ModelAttribute("dataAccountCommand") final DataAccountCommand dataAccountCommand, 
                                    Errors errors) {


        validator.validate(dataAccountCommand, errors);
}

}

But then I got another strange error:

java.lang.AbstractMethodError: org.hibernate.ejb.HibernatePersistence.getProviderUtil()Ljavax/persistence/spi/ProviderUtil; 

Upvotes: 0

Views: 388

Answers (1)

Nikolay Rusev
Nikolay Rusev

Reputation: 4230

I didn't see where you validate your @ModelAttribute("dataAccountCommand"). Add your validation logic somewhere.

Please see their reference documentation. You have two options:

The first one is with custom validator:

@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) {

    new PetValidator().validate(pet, result);
    if (result.hasErrors()) {
        return "petForm";
    }

    // ...

}

the second one is with @Valid Annotation:

@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) {

    if (result.hasErrors()) {
        return "petForm";
    }

    // ...
}

Leave only modelAttribute and BindingResult as input arguments for your method. EDIT:

   @RequestMapping(value = "/accounts/saveaccount.do", method = RequestMethod.POST)
    private String saveAccount  (   @Valid @ModelAttribute("dataAccountCommand") final DataAccountCommand dataAccountCommand, 
                                    BindingResult result) {

        return "registerAccountView";

    }  

Upvotes: 1

Related Questions