2015-03-05 7 views
0

Загружаю существующий объект пользователя как @ModelAttribute в форму Spring (и он правильно отображает соответствующий идентификатор и имя), но когда я изменяю имя и пытаюсь прочитать его обратно на submit, я получаю нуль ID в processEditSubmit (имя правильно изменено).Spring MVC @ModelAttribute zero ID из формы

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"; 

    } 

} 

ответ

0

В вашем JSP, вы упоминают disabled = true. Когда вы это сделаете, браузер не отправит это значение поля на сервер (это можно проверить с помощью инструментов Chrome Dev или плагина Firebug на FF). Поэтому в вашем контроллере значение поля id равно нулю, потому что это целочисленный примитивный тип, и все примитивы экземпляров инициализируются значением по умолчанию.

Почему бы не использовать readOnly = true вместо этого?

Смежные вопросы