How can I validate a complex model object in Spring 3 using @Valid annotations?

I have a model object modelling a purchase order. The purchase order has a few fields (such as ID and date) and a list of line-items as ArrayList. I can validate the parent purchase order ok, but it chokes when validating the line-items.

Can anyone help me with validation of complex objects? If I cannot validate complex objects auto-magically, how can I write a custom validator that relies upon the constraint annotations in the parent and then iterates over the child line-items? This Validator instance needs to be able to call something.validate(purchaseOrder) and (for each line-item) something.validate(lineItem). Where do I get "something" from?

I have specified <mvc:annotation-driven /> in dispatcher-servlet. I am not using @InitBinder. And I am using @Valid annotation for validation in controller's method like

    @RequestMapping(params="confirmPurchaseOrder")
    public String confirm(
            @ModelAttribute("purchaseOrder") @Valid PurchaseOrder purchaseOrder,
            BindingResult result,
            @RequestParam("account") String accountString,
            @RequestParam("division") String divisionString,
            Model model)
    {
        if (result.hasErrors()) {
            return PURCHASE_ORDER_CREATE_VIEW;
        }

The domain classes look like this: -

public class PurchaseOrder implements Comparable<PurchaseOrder> {
    /** Based on GUID */
    private String id;

    /** SOP */
    @NotNull
    private Integer SOP;

    /** Reference from client */
    @NotBlank
    private String purchaseOrderReference;

    /** PO date */
    @DateTimeFormat(style="S-")
    @NotNull
    private Date date;

    @Valid
    private final Collection<LineItem> lineItems = new ArrayList<LineItem>();

And

public class LineItem {
    ...Elided

    /** Generated from GUID */
    private String id;

    @NotNull
    @DateTimeFormat(style="S-")
    @Future
    private Date expiry;

    private String softwareVersion;

    @NotNull
    @NumberFormat(style = Style.NUMBER)
    @Min(1)
    private Integer licenceCount;

When committing a Purchase Order with an empty expiry date, I get the following exception:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'lineItems[]' of bean class [com.nit.ols.domain.PurchaseOrder]: Invalid index in property path 'lineItems[]'; nested exception is java.lang.NumberFormatException: For input string: ""
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:730)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:634)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

Answers


In your PurchaseOrder class, try changing your lineItems collection to a List. It looks like you are having the same problem addressed in this question.


Need Your Help

Can't create table (errno:121) when importing mysql workbench export dump only on Linux

mysql linux hibernate mysql-workbench

I created a .sql dump file by exporting my tables using MySQL Workbench on a Windows machine. If I try to import that file again on Windows, everything works fine. If I try to import that file using

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.