2014-01-27 131 views
1

这将会有点复杂,但请耐心等待。我有一个拥有多个属性的bean学生,我注释了所有需要使用Hibernate注释验证的属性。当我想要为学生进行搜索时,我只需要一些注释/验证的属性,但是对所有这些属性都进行了验证,这些验证不允许搜索正确执行。使用Hibernate进行Spring MVC和bean验证

这是学生豆:

@Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(name = "STUDENT_ID", unique = true, nullable = false) 
    private Integer studentId; 

    @NotNull(message = "First name is null!") 
    @NotBlank(message = "Please enter first name!") 
    @Column(name = "FIRST_NAME", nullable = false, length = 50) 
    private String firstName; 

    @NotNull(message = "Last name is null!") 
    @NotBlank(message = "Please enter last name!") 
    @Column(name = "LAST_NAME", nullable = false, length = 50) 
    private String lastName; 

    @NotNull(message = "MK is null!") 
    @NotBlank(message = "Please enter MK!") 
    @Column(name = "MK", nullable = false, length = 2) 
    private String mk; 

    @NotNull(message = "Roll number is null!") 
    @NotBlank(message = "Please enter roll number!") 
    @Column(name = "ROLL_NUMBER", nullable = false, length = 4) 
    private String rollNumber; 

    @NotNull(message = "Roll year is null!") 
    @NotBlank(message = "Please enter roll year!") 
    @Column(name = "ROLL_YEAR", nullable = false, length = 4) 
    private String rollYear; 

    //not populated by user, no validation needed 
    @Column(name = "INDEX_NUMBER", unique = true, nullable = false, length = 20) 
private String indexNumber; 

    //for populating MK field only, no validation needed 
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER) 
    @JoinColumn(name = "PROGRAM_FK", nullable = false) 
    private Program program; 

这是控制器:

@RequestMapping(value="/search", method = RequestMethod.POST) 
    public String postSearchStudent(
      @RequestParam(value = "mk") String programId, 
      @RequestParam(value = "rollNumber") String rollNumber, 
      @RequestParam(value = "rollYear") String rollYear, 
      @RequestParam(value = "indexNumber") String indexNumber, 
      @Valid @ModelAttribute("searchStudentAttribute") Student student, 
      BindingResult result, 
      Model model) { 

     logger.debug("Received request to search for a student"); 

     if (result.hasErrors()) { 
      model.addAttribute("programList", programService.getAll()); 
      return "searchStudent"; 
     } 
     else { 
      student = studentService.search(indexNumber); 
      // if student isn't in the db show add student page, else redirect to student page 
      if (student == null) { 
       student = new Student(); 
       student.setRollNumber(rollNumber); 
       student.setRollYear(rollYear); 
       student.setIndexNumber(indexNumber); 
       Program program = programService.get(programId); 
       student.setProgram(program); 
       model.addAttribute("student", student); 
       return "addStudent"; 
      } 
      else { 
       Integer studentId = student.getStudentId(); 
       model.addAttribute("studentId", studentId); 
       return "redirect:/essays/main/student/{studentId}"; 
      } 
     } 
    } 

这是视图:

<c:url var="searchUrl" value="/essays/main/student/search" /> 
<form:form modelAttribute="searchStudentAttribute" method="POST" action="${searchUrl}"> 
<form:errors path="*" cssClass="errorblock" element="div" /> 

<form:label path="program">Select program (MK):</form:label> 
<form:select path="program" id="programSelect" size="8"> 
    <form:options items="${programList}" itemValue="programId" itemLabel="programDescription" />    
</form:select> 

<form:label path="mk">MK</form:label> 
<form:input path="mk" id="mkInput" size="2" maxlength="2"/> 
<form:errors path="mk" cssClass="error"/> 

<form:label path="rollNumber">Roll number</form:label> 
<form:input path="rollNumber" id="rollNumberInput" size="4"/> 
<form:errors path="rollNumber" cssClass="error"/> 

<form:label path="rollYear">Roll year</form:label> 
<form:input path="rollYear" id="rollYearInput" size="4" maxlength="4"/> 
<form:errors path="rollYear" cssClass="error"/> 

<form:label path="indexNumber" /> 
<form:hidden path="indexNumber" id="indexNumberInput" /> 

<input type="submit" value="Submit" onclick="makeIndexNumber();"/> 
</form:form> 

正如你所看到的,名字和姓氏学生与搜索无关,因为搜索是由几个其他属性组合成一个你唱javaScript。但是我需要后面第一个和最后一个名字进行验证,比如说,添加新学生,所以我不能只删除注释并且根本不验证这些字段。有人可以告诉我,我应该做一个单独的bean进行验证只是为了用于搜索学生,还是有其他适当的解决方案呢?

让我更图文:

enter image description here

当我提交表单的所有字段为空,我得到这些错误。我如何告诉它在搜索完成时不考虑名字和姓氏属性,而不删除用于验证的注释?

回答

2

这是使用验证组的好方案。为了得到一个想法有关验证组检查此链接 -

Validation Groups

标准@​​Valid注释仍然不支持组。所以,你可以使用Spring特定的@Validated注释和验证组。

@Validated

0

@NotNull注释表明您不能将null值赋值给带注释的变量。我看不到你在你提供的代码中的任何位置执行此操作,但这里是我的想法:

当你传递一个对象到Spring MVC时,它创建它自己的对象表示,可用于生成jsp - 类。当您提交表单时,转换将以另一种方式进行,它将使用set-方法重新创建原始对象。因此,当您创建新的Student时,firstNamelastName变量将为null,这很好。然后你将它传递给Spring MVC,它将两个变量值转换为null。但是,在提交表格后,Spring MVC试图翻译回去,并且确实setFirstName(null),然后就有麻烦了。

有几种方法可以解决这种情况。

  1. 最简单的一个,只是将它传递给Spring MVC之前设置firstNamelastName变量“”(空字符串)。然后它将永远不会尝试给它们赋值一个null值,它将是空字符串。
  2. 优雅的一个,创建一个新类StudentSearchCommand或类似的东西,它将作为搜索对话框的后盾对象。这个类应该具有执行搜索所需的字段,所以除了名字和姓氏,除了没有验证外,所有的东西都有Student,也没有JPA注释(只是Plain Ol'Java Object(POJO))。实例化此类并将其发送到Spring MVC,并在提交表单时,从中选取值并填充Student-对象。通过这种方式,您可以超越Spring MVC对您的域类(例如“必须拥有一个setter”)的要求,并按照您的意愿和想要的方式保持它们。
+0

感谢您的回答@Tobb!关于第一个建议:我还使用@NotBlank注释了我的bean属性,因此不要将第一个和最后一个名称设置为空字符串,仍然会导致“请输入第一个/姓氏!”错误?关于第二个建议 - 我会尽力回复。 –

+0

是的,它可能会。第二种解决方案可能是要走的路。有可能没有'@ NotNull'和'@ NotBlank'注解,我以前从未使用过它们。但是如果你必须包含它们,那么最好是完全控制这个类,并且不要将它传递给第三方(Spring MVC)。 – Tobb

+0

此外,您可以尝试将其设置为一些任意字符串,以查看错误消息是否消失(然后知道它实际上是由Spring MVC与对象交互引起的)。 – Tobb

相关问题