在使用Spring MVC和Hibernate更新之前,如何预填充对象? [英] How to prepopulate an object before updating using spring mvc and hibernate?

查看:82
本文介绍了在使用Spring MVC和Hibernate更新之前,如何预填充对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在用休眠保存该对象之前预填充对象的最佳实践是什么?

我做了什么:

我的控制器:

//The Form
@RequestMapping(value = "user/{id}/edit", method = RequestMethod.GET)
public String edit(@PathVariable("id") Long userId, ModelMap modelMap) {
    modelMap.addAttribute("user", userService.find(userId));    
    return "user/userEdit";

}
//Updating database
@RequestMapping(value = "user/edit", method = RequestMethod.POST)
public String update(@ModelAttribute("user") @Valid User user, BindingResult result,
                                                RedirectAttributes redirectAttrs) {
    if (result.hasErrors()) {
            return "user/userEdit";
    }else{
        userService.update(user);
        redirectAttrs.addFlashAttribute("message", "Success");

        return "redirect:user/userEdit";
    }
}

如果我创建一个包含所有字段(用户名,密码和ID)的表单,它会起作用,但是如果我希望用户仅更新密码,该怎么办?

由于我在用户名处使用@NotEmpty,因此我收到一个错误,提示用户名为null,因为它的格式不是,但我不想输入用户名字段,而只输入密码.

我的html表单:

<c:url var="url" value="/user/edit" />
<form:form method="post" action="${url}" modelAttribute="user" class="form-horizontal">
    <form:hidden path="id"/>
    <form:hidden path="version"/>
    <fieldset>
        <div class="control-group">
            <form:label cssClass="control-label" path="password"><spring:message code="user.label.password"/>: </form:label>
            <div class="controls">
                <form:input cssClass="input-xlarge" path="password" />
            </div>
            <form:errors path="password"/>
        </div>
        <div class="control-group">
            <form:label cssClass="control-label" path="userRole"><spring:message code="user.label.role"/>: </form:label>
            <div class="controls">
                <form:select path="userRole">
                       <form:options items="${userRoleList}" itemValue="id" itemLabel="name"/>
                </form:select>
            </div>
            <form:errors path="userRole"/>
        </div>
        <div class="control-group">
            <form:label cssClass="control-label" path="costumer.id"><spring:message code="user.label.costumer"/>: </form:label>
            <div class="controls">
                <form:select path="costumer.id">
                       <form:options items="${costumerList}" itemValue="id" itemLabel="name"/>
                </form:select>
            </div>
            <form:errors path="costumer.id"/>
        </div>

        <div class="form-actions">
            <button type="submit" class="btn btn-primary">Save changes</button>
            <a class="btn cancel link" href="<c:url value="/user" />">Cancel</a>
        </div>
    </fieldset>
</form:form>

  • 我尝试使用@Sessionattributes,但是如果我尝试使用@Sessionattributes,它将无法正常工作 使用浏览器标签编辑两个或多个用户.
  • 我尝试使用属性编辑器,但未与@ModelAtrribute一起使用 用户用户.
  • 我尝试使用转换器,但没有用.

唯一的方法是首先使User用户= userService.find(id),然后设置更新的值吗?像这样:

@RequestMapping(value = "user/edit", method = RequestMethod.POST)
public String update(@RequestParam("password") String password, BindingResult result, RedirectAttributes redirectAttrs) {
    User user = userService.find(id);
if (password == null{                           
    return "user/userEdit";
}else{
    user.setPassword("password");
    userService.update(user);
    redirectAttrs.addFlashAttribute("message", "Success");

    return "redirect:user/userEdit";
}
}

这是错误的,因为没有验证.

解决方案

例如,我认为不太杂乱且不易出事的另一种方法是创建一个对UI表单进行建模的类

public class EditUserForm {
    // getters and setters for password and other fields...
}

并在控制器的update(EditUserForm,...)方法中,只需将用户在EditUserForm中填充的所有字段映射到要更新的User实例.

What's the best practice to pre-populate an object before saving this object with hibernate?

What i've done:

My controller:

//The Form
@RequestMapping(value = "user/{id}/edit", method = RequestMethod.GET)
public String edit(@PathVariable("id") Long userId, ModelMap modelMap) {
    modelMap.addAttribute("user", userService.find(userId));    
    return "user/userEdit";

}
//Updating database
@RequestMapping(value = "user/edit", method = RequestMethod.POST)
public String update(@ModelAttribute("user") @Valid User user, BindingResult result,
                                                RedirectAttributes redirectAttrs) {
    if (result.hasErrors()) {
            return "user/userEdit";
    }else{
        userService.update(user);
        redirectAttrs.addFlashAttribute("message", "Success");

        return "redirect:user/userEdit";
    }
}

It works if i make a form containing all fields (username, password and id) , but what should i do if i want the user to update only the password?

Since i have a @NotEmpty at username, i get an error that username is null, since its not in the form, but i dont want to put the username field, just the password.

My html form:

<c:url var="url" value="/user/edit" />
<form:form method="post" action="${url}" modelAttribute="user" class="form-horizontal">
    <form:hidden path="id"/>
    <form:hidden path="version"/>
    <fieldset>
        <div class="control-group">
            <form:label cssClass="control-label" path="password"><spring:message code="user.label.password"/>: </form:label>
            <div class="controls">
                <form:input cssClass="input-xlarge" path="password" />
            </div>
            <form:errors path="password"/>
        </div>
        <div class="control-group">
            <form:label cssClass="control-label" path="userRole"><spring:message code="user.label.role"/>: </form:label>
            <div class="controls">
                <form:select path="userRole">
                       <form:options items="${userRoleList}" itemValue="id" itemLabel="name"/>
                </form:select>
            </div>
            <form:errors path="userRole"/>
        </div>
        <div class="control-group">
            <form:label cssClass="control-label" path="costumer.id"><spring:message code="user.label.costumer"/>: </form:label>
            <div class="controls">
                <form:select path="costumer.id">
                       <form:options items="${costumerList}" itemValue="id" itemLabel="name"/>
                </form:select>
            </div>
            <form:errors path="costumer.id"/>
        </div>

        <div class="form-actions">
            <button type="submit" class="btn btn-primary">Save changes</button>
            <a class="btn cancel link" href="<c:url value="/user" />">Cancel</a>
        </div>
    </fieldset>
</form:form>

  • I tried using @Sessionattributes, but it doesnt work well if i try to edit two or more users using browser tabs.
  • I tried using property editors, but didnt work with @ModelAtrribute User user.
  • I tried using convertors but didnt work.

Is the only way to make a User user = userService.find(id) first, and then set the updated values? Something like:

@RequestMapping(value = "user/edit", method = RequestMethod.POST)
public String update(@RequestParam("password") String password, BindingResult result, RedirectAttributes redirectAttrs) {
    User user = userService.find(id);
if (password == null{                           
    return "user/userEdit";
}else{
    user.setPassword("password");
    userService.update(user);
    redirectAttrs.addFlashAttribute("message", "Success");

    return "redirect:user/userEdit";
}
}

Which seens wrong, because there is no validation.

解决方案

An alternate way, that I think is less messy and accident-prone, is to create a class that models the UI form, for example

public class EditUserForm {
    // getters and setters for password and other fields...
}

and in the controller's update(EditUserForm,...) method, you simply map any fields populated by the user in the EditUserForm to the instance of User you wish to update.

这篇关于在使用Spring MVC和Hibernate更新之前,如何预填充对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆