Search code examples
spring-mvcspring-bootthymeleaf

Thymeleaf Spring MVC form - Neither BindingResult nor plain target object for bean name


I have a thymeleaf form that is throwing the following exception after it's submitted

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute

I've read a couple of answers which suggests putting a BindingResult directly after the model attribute in the controller method but this doesn't seem to have solved it. Here's what I have

<form action="#" th:action="@{/capturedetails}" th:object="${command}" method="post">
  <div class="form-group" th:if="${mobilePhone} == null">
    <label for="mobilePhone">Mobile Phone</label> <input
      type="tel" class="form-control"
      id="mobilePhone"
      placeholder="Mobile Phone no." th:field="*{mobilePhone}"></input>
  </div>
  <div class="form-group" th:if="${secondEmail} == null">
    <label for="secondEmail">Secondary Email</label>
    <input type="email" class="form-control"
      id="secondEmail" placeholder="Secondary Email" th:field="*{secondEmail}"></input>
  </div>
  <button type="submit">Submit</button>
</form>

The controller method

@PostMapping(value = "/capturedetails")
public String updateProfile(@ModelAttribute("command") CaptureDetailsFormCommand command, BindingResult bindingResult, Model model) {
    model.addAttribute("command", command);
    return "redirect: someWhere";
}

And the command object

public class CaptureDetailsFormCommand {

    private String mobilePhone;

    private String secondEmail;

    public String getMobilePhone() {
        return mobilePhone;
    }

    public void setMobilePhone(String mobilePhone) {
        this.mobilePhone = mobilePhone;
    }

    public String getSecondEmail() {
        return secondEmail;
    }

    public void setSecondEmail(String secondEmail) {
        this.secondEmail = secondEmail;
    }

}

Solution

  • OK in my usual style, solved it myself. The problem was actually in the Get Mapping not the post mapping eg. I needed

    @GetMapping(value = "/capturedetails")
    public ModelAndView captureDetails() {
        ModelAndView mav = new ModelAndView("capturedetails");
        mav.addObject("command", new CaptureDetailsFormCommand());
        return mav;
    }