我有两个实体,它们是:Person 和 Address,一对一的关系。关于 JPA/Hibernate 的源代码已被删除以保持简单。
我的问题是休眠验证器。
对于Person类,我有以下内容:
@Valid
@NotNull(message="{person.address.null}", groups={AddressCheck.class})
public Address getAddress() {
return address;
}
和地址:
@NotNull(message="{field.null}", groups=AddressCheck.class)
public Person getPerson() {
return person;
}
注意:关于 JUnit,一切正常,如果某些依赖项为空,则会创建相应的错误。
问题是当 Hibernate Validator与 Spring MVC集成时,它通过绑定的方式
关于视图代码,在 Address 类的 JSP 片段下方
<form:form modelAttribute="person" method="post" >
...
<fieldset>
<legend><spring:message code="address.form.legend"/></legend>
<table>
<form:hidden path="address.id"/>
<tr>
<td><spring:message code="address.form.street"/></td>
<td><form:input path="address.street" size="40"/></td>
<td><form:errors path="address.street" cssClass="error"/></td>
</tr>
<tr>
<td><spring:message code="address.form.number"/></td>
<td><form:input path="address.number" size="40"/></td>
<td><form:errors path="address.number" cssClass="error"/></td>
</tr>
</table>
</fieldset>
要创建表单视图,让 JSP 呈现这两个对象,我有以下内容:
@RequestMapping(value="/register.htm", method=RequestMethod.GET)
public String createRegisterForm(Model model){
logger.info("createRegisterForm GET");
Person person = new Person();
Address address = new Address();
address.setId("5");//just to play/test
person.setAddress(address);
address.setPerson(person);
model.addAttribute("person", person);
return "jsp/person/registerForm";
}
观察这两个 setter 是如何被调用的。
当我提交时,必须执行以下代码
@RequestMapping(value="/register.htm", method=RequestMethod.POST)
public String registerPerson( @Validated(PersonRegistrationOrdered.class) Person person,
BindingResult result,
Model model){
logger.info("registerPerson POST");
logger.info("{}", person.toString());
logger.info("{}", person.getAddress().toString());
if(result.hasErrors()){
logger.error("There are errors!!!!");
model.addAttribute("person", person);
for(ObjectError objectError : result.getAllErrors()){
logger.error("Error {}", objectError);
}
return "jsp/person/registerForm";
}
logger.info("All fine!!!!");
return "jsp/manolo";
}
遗憾的是,控制台显示有关 Address 类中的 Person 对象的错误为 null,即使在createRegisterForm中它已经相关address.setPerson(person);
我解决此问题的独特方法是禁用验证
//@NotNull(message="{field.null}", groups=AddressCheck.class)
public Person getPerson() {
return person;
}
第一个问题:如何在不禁用@NotNull
验证的情况下避免这种情况?
更重要的是,如果我想保护Address 类的id :
@InitBinder
public void initBinder(WebDataBinder binder) {
...
binder.setDisallowedFields("address.id");
}
从 JSP 文件生成的 HTML 代码是
<fieldset>
<legend>Address:</legend>
<table>
<input id="address.id" name="address.id" type="hidden" value="5"/>
<tr>
<td>Street:</td>
<td><input id="address.street" name="address.street" type="text" value="" size="40"/></td>
<td></td>
</tr>
<tr>
<td>Number:</td>
<td><input id="address.number" name="address.number" type="text" value="" size="40"/></td>
<td></td>
</tr>
</table>
</fieldset>
但是当我再次提交时,我得到了
- ValidationMessages found.
- org.hibernate.validator.ValidationMessages found.
- registerPerson POST
- Person [id=5, firstName=Manuel, lastName=Jordan, alive=true, dateBirth=Wed Dec 12 00:00:00 PET 2012, dateRetirement=null, dateDeath=null, age=15, weight=34.0, salary=1500]
- Address [id=null, street=La blanquita, number=155]
- There are errors!!!!
- Error Field error in object 'person' on field 'address.id': rejected value [null]; codes [NotNull.person.address.id,NotNull.address.id,NotNull.id,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.address.id,address.id]; arguments []; default message [address.id]]; default message [The field must be not empty]
如果我正在创建一个新的 Person 并使用一个特殊的类,address.setId("5");
为地址的 id 提供一个潜在的 id(例如在本例中为 5),这将是一个问题。
第二个问题:我怎样才能扭转这个问题?