Fitrah M
Fitrah M

Reputation: 993

Spring MVC : How To Get BindingResult Error Field for Nested Object

I submit this data to add a Child entity via Ajax (POST):

(See the bottom of this question for entity classes definition)

name = "Child Name"
parent.id = 3

Everything is OK. The new Child entity is saved successfully.

But If don't include the parent.id (only name is set) (submitted using POST method)

name = "Child Name"

The validation result return this JSON:

"errors":{"parent":"may not be null"}

Note the "parent" property in that JSON. It's supposed to return parent.id not parent.

It causes problem as the field on client-side script (HTML) has the name "parent.id" not "parent".

Any suggestion How to return parent.id instead of parent ??

Here is the handler method:

@RequestMapping(value = "/add", method = RequestMethod.POST)
@ResponseBody
public Map<String, ?> add(@Valid Child child, BindingResult result) {

    Map<String, ?> out = new LinkedHashMap<String, ?>();

    if(result.hasErrors()){
        Map<String, String> errors = new LinkedHashMap<String, String>();
        for (FieldError error : result.getFieldErrors()) {
           errors.put(error.getField(), error.getDefaultMessage());
        }
        out.put("success", false);
        out.put("errors", errors);
        return out;
    } else {
        out.put("success", true);
    }

    return out;

}

And here are the entity classes:

class Child {
    private int id;

    @NotNull
    @Size(min = 5)
    private String name;

    @NotNull        
    private Parent parent;

    //getter and setter methods
}

class Parent {
    private int id;

    @NotNull
    private String name;

    //getter and setter methods
}

Thank you.

Upvotes: 1

Views: 7133

Answers (2)

Fitrah M
Fitrah M

Reputation: 993

Thanks for @oehmiche for the suggestion.

I end up changing the entity classes to these:

class Child {
    @NotNull
    private int id;

    @NotNull
    @Size(min = 5)
    private String name;

    @NotNull
    @Valid
    private Parent parent = new Parent("Foo Foo");

    //getter and setter methods
}

class Parent {
    @NotNull
    private int id;

    @NotNull
    private String name;

    public Parent(){
    }

    public Parent(String name){
         setName(name);
    }

    //getter and setter methods
}

And this is the submitted data:

id = 1
name = "Child Name"
parent.id = 3

Note the id property. I end up to always set this to 1 just to bypass the @NotNull constraint. Although the id value will always be replaced by Hibernate (I use auto generation strategy).

(I add @NotNull constraint for id of Parent as well as Child class for consistency)

However, there is still one problem. I have to always set parent's name just to bypass the validation constraint for name property of Parent:

@NotNull
@Valid
private Parent parent = new Parent("Foo Foo");

Any suggestion for this?

Upvotes: 2

oehmiche
oehmiche

Reputation: 1028

According to the hiberante validation specification object graph validation is triggered using the @Valid on the property to be validate (in your case the parent property). But there is also mentioned that null values will be ignored (see the note below the example). So in your case I'd suggest to instantiate an empty Parent object in your Child class and annotate that one with @Valid:

@Valid        
private Parent parent = new Parent();

see also https://stackoverflow.com/a/5142960/160729

Upvotes: 2

Related Questions