简体   繁体   中英

Spring MVC @ModelAttribute zero ID from form

I load existing User object as @ModelAttribute into a Spring Form (and it correctly displays corresponding ID and Name), but when I modify Name and try to read it back on submit I get zero ID in processEditSubmit (name is correctly changed).

User.java

@Entity
@Table(name = "\"user\"")
public class User {

    @Id
    // @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private int id;

    @Column
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

EditUser.jsp

<table>
    <form:form modelAttribute="userCmd" action="update" method="post" >
        <tr><td>ID:</td><td><form:input disabled="true" path="id" /></td><td><form:errors path="id" cssClass="error"/></td></tr>
        <tr><td>Name:</td><td><form:input path="name"/></td><td><form:errors path="name" cssClass="error"/></td></tr>
        <tr><td colspan="3"><input type="submit" value="Save"/></td></tr>
    </form:form>
</table>

ManageUsers.java

@Controller
@RequestMapping("/users")
public class ManageUsers {

    @Autowired
    private UserValidator userValidator;

    @Autowired
    private UserManager userManager;

    @InitBinder
    private void initBinder(WebDataBinder binder) {
        // binder.setValidator(userValidator);
        // binder.registerCustomEditor(User.class, new UserEditor());
    }

    @RequestMapping(method = RequestMethod.GET)
    public String viewUsers(ModelMap model) {
        UserList ul = new UserList();
        List<User> users = userManager.getUsers();
        ul.setUserList(users);
        model.addAttribute("userListCmd", ul);
        return "manageUsers";
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String editUser(@RequestParam int id, ModelMap model) {
        model.addAttribute("userCmd", userManager.getUserById(id));
        return "editUser";
    }

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String addUser(ModelMap model) {
        model.addAttribute("userCmd", new User());
        return "addUser";
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String processAddSubmit(@ModelAttribute("userCmd") User user,
            BindingResult result, SessionStatus status,
            HttpServletResponse response) throws IOException {

        userValidator.validate(user, result);

        if (result.hasErrors())
            return "addUser";

        userManager.insertUser(user);
        status.setComplete();

        return "redirect:/users";

    }

    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String processEditSubmit(@ModelAttribute("userCmd") User user,
            BindingResult result, SessionStatus status,
            HttpServletResponse response) throws IOException {

        userValidator.validate(user, result);

        if (result.hasErrors())
            return "editUser";

        // user contains zero ID and operation fails with org.hibernate.StaleStateException: 
        // Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
        userManager.updateUser(user);

        status.setComplete();

        return "redirect:/users";

    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public String processDelete(@PathVariable int id,
            HttpServletResponse response) throws IOException {

        userManager.deleteUser(id);

        return "redirect:/users";

    }

}

In your jsp, you are mentioning disabled=true. When you do this, the browser will not send this field value back to the server (You can verify this by Chrome Dev tools or Firebug plugin on FF). So in your controller, id field value is zero, because it is an integer primitive type and all instance primitives are initialized to default value.

Why not use readOnly=true instead?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM