2012-05-22 38 views
0

在用hibernate保存這個對象之前預先填充對象的最佳做法是什麼?如何使用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在用戶名,我得到一個錯誤,用戶名爲空,因爲它不是在窗體中,但我不想把用戶名字段,只是密碼。

我的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,但它不工作得很好,如果我嘗試 編輯使用的瀏覽器選項卡兩個或多個用戶。
  • 我試過使用屬性編輯器,但沒有用@ModelAtrribute 用戶用戶。
  • 我試過使用轉換器,但沒有工作。

首先創建User 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"; 
} 
} 

哪個出現錯誤,因爲沒有驗證。

回答

0

的另一種方法,我認爲是不太混亂和事故多發,是創建一個類車型UI形式,例如

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

,並在控制器的update(EditUserForm,...)方法,只需使用地圖的任何字段填入用戶在EditUserForm到您想要更新的User的實例。

+0

看起來像我的最後一個例子(但我的ModelAttribute和UserService中有兩個對象),但它不會傳遞@Valid,並且不會返回錯誤與BindingResult。只有當我在EditUserForm和User中都進行了hibernate驗證的時候。 我弄錯了嗎? – kenji

+0

對不起,如果我不清楚,但我的建議是,控制器不會將'User'放入模型中,也不會將'update()'方法包含簽名中的'User'。 'edit()'應該將'EditUserForm'形式支持對象的一個​​實例放入模型中,'update()'方法簽名應該看起來像'update(@ModelAttribute(「user」)@Valid EditUserForm userForm,BindingResult結果,RedirectAttributes redirectAttrs)' –

+0

對不起這些問題,但你可以看到新的Java /春/休眠世界,並盡我所能以正確的方式做到這一點。所以讓我看看我是否理解:1.創建一個UserEditForm類並在其中放入驗證註釋; 2.在我的edit()控制器方法中,我應該創建一個UserEditForm的實例,並使用userService.find(id)設置它的屬性並將其發送到視圖; 3當我收到它在控制器方法更新()我應該將UserEditForm發送到userService.changePassword(UserEditForm),然後我應該做user.setPassword(UserEditForm.getPassword())? – kenji

0

在您發佈的代碼中,很明顯您需要一些外部幫助類來與您的GUI端更新相關聯,然後才能實現移動控制和持久性操作。

0

我也遇到過這個問題,如果只有幾個字段,我使用你的第二個例子並逐個驗證字段。否則,你將不得不做其他海報所說的話,並且創建一個新的類來匹配你的表單。

0

嘗試使用:

@PrePersist
@PreUpdate
公共無效的準備(){
  //做一些與你的實體   //例如:如果(名稱== NULL) {name =「MYNAMEVALUE」;}
}

相關問題