Spring Framework - 在 DB 中创建新对象而不是更新

Jar*_*son 1 spring spring-mvc

我有一个用 Spring 3.0 编写的应用程序,它使用 Hibernate 连接到数据库。我有一个更新表单的控制器。每当提交表单时,我都希望显示的对象被更新,但是会创建一个具有新 ID 值的新对象。我查看了“petclinic”样本,我看不出它有什么不同。

POJO

public class Person
{
    private int id;

    @NotNull
    private String name;

    //getter/setter for id
    //getter/setter for name

}
Run Code Online (Sandbox Code Playgroud)

控制器

public class PersonUpdateController
{
    //injected
    private PersonService personService;

    @RequestMapping(value="/person/{personId}/form", method=RequestMethod.POST) 
    public String updateForm(ModelMap modelMap, @PathVariable personId)
    {
        Person person = personService.getById(personId);
        modelMap.addAttribute(person);
        return "person/update";     
    }

    @RequestMapping(value="/person/{personId}", method=RequestMethod.POST)
    public String update(ModelMap modelMap, @Valid Person person, BindingResult bindingResult)
    {
        if(bindingResult.hasErrors())
        {
            modelMap.addAttribute(person);
            return "person/update";
        }

        personService.save(person);

        return "redirect:person/" + person.getId() + "/success";
    }
}
Run Code Online (Sandbox Code Playgroud)

JSP

<spring:url value="/person/${person.id}" var="action_url" />
<spring:form action="${action_url}" modelAttribute="person" method="POST">

<spring:input name="name" path="name" />

<input type="submit" value="Save" />

</spring:form>
Run Code Online (Sandbox Code Playgroud)

人员服务实现

public class HibernatePersonService
    implements PersonService
{
    //injected
    private SessionFactory sessionFactory;

    //other methods

    public void save(Person person)
    {
        Session session = sessionFactory.getCurrentSession();
        session.saveOrUpdate(person);
    }
}
Run Code Online (Sandbox Code Playgroud)

axt*_*avt 5

Spring MVC 对 HTML 表单没有任何魔力。由于您的表单仅包含一个字段,因此您只会在 update 方法中填充一个字段。所以,你有两个选择:

  • id作为以下形式的隐藏字段传递:<spring:hidden path = "id" />。请注意,在这种情况下,您需要检查可能的安全后果(如果恶意人员更改 id 会发生什么)。
  • 存储Person在会话中,以便使用表单中的数据来更新存储的对象(请注意,如果在一个会话中打开多个表单实例,可能会造成干扰)。这就是在 Petclinic 中的做法:

——

@SessionAttributes("person")
public class PersonUpdateController {
    ...

    @RequestMapping(value="/person/{personId}", method=RequestMethod.POST) 
    public String update(ModelMap modelMap, @Valid Person person, 
        BindingResult bindingResult, SessionStatus status) 
    { 
        ...
        personService.save(person);
        status.setComplete(); // Removes person from the session after successful submit
        ...
    }

    @InitBinder
    public void setAllowedFields(WebDataBinder dataBinder) {
        dataBinder.setDisallowedFields("id"); // For security
    }
}
Run Code Online (Sandbox Code Playgroud)