我正在使用 Spring Boot 1.5.4.RELEASE 和 Spring Data JPA 进行项目。
遇到更新实体时未执行 Hibernate 验证器或至少在某些情况下未验证的问题。
For Person如下所示,禁止使用空名称,并且技能集合必须至少包含 1 个元素,最多包含 5 个元素。
两者均在通话过程中得到验证save在 Spring 数据存储库上。但是,对于现有实体上的调用保存,它将仅验证名称约束 - 而不会检查技能。
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
@NotBlank
private String name;
@ElementCollection(fetch = FetchType.EAGER)
@Size(min = 1, max = 5)
private Set<String> skills = new HashSet<>();
protected Person() {
}
public Person(final String name, final Collection<String> skills) {
this.name = name;
this.skills.addAll(skills);
}
public void updateSkills(Collection<String> skills) {
this.skills.clear();
this.skills.addAll(skills);
}
public void updateName(final String name) {
this.name = name;
}
//getters
}
当使用空技能列表创建新实体时,它将按预期抛出 ConstraintValidationException:
@Test(expected = ConstraintViolationException.class)
public void shouldFailWhenSkillsAreEmpty() {
//given
Person person = new Person("gucio", Collections.EMPTY_LIST);
//when
personRepository.save(person);
//then
}
https://github.com/konczak/demo-skills-validation-issue/blob/master/src/test/java/com/example/demo/entity/PersonTest.java#L80 https://github.com/konczak/demo-skills-validation-issue/blob/master/src/test/java/com/example/demo/entity/PersonTest.java#L80
然而,当做同样的事情时 - 在实体更新上存储空列表(合并底层?不确定)它会通过,而我预计会出现异常:
@Test(expected = ConstraintViolationException.class)
public void shouldFailWhenUpdateSkillsToEmpty() {
//given
Person person = new Person("gucio", Arrays.asList(JAVA, SQL));
person = personRepository.save(person);
person.updateSkills(Collections.EMPTY_LIST);
//when
personRepository.save(person);
//then
}
https://github.com/konczak/demo-skills-validation-issue/blob/master/src/test/java/com/example/demo/entity/PersonTest.java#L104 https://github.com/konczak/demo-skills-validation-issue/blob/master/src/test/java/com/example/demo/entity/PersonTest.java#L104
我已经使用手动创建的验证器编写了测试并验证了此类 Person,正如预期的那样,它针对现场技能返回 1 ConstraintViolation:
https://github.com/konczak/demo-skills-validation-issue/blob/master/src/test/java/com/example/demo/entity/PersonTest.java#L119 https://github.com/konczak/demo-skills-validation-issue/blob/master/src/test/java/com/example/demo/entity/PersonTest.java#L119
您可以轻松查看示例项目:
https://github.com/konczak/demo-skills-validation-issue https://github.com/konczak/demo-skills-validation-issue
我明白下面有一个区别save瞬态和附加/分离实体的方法,但我仍然希望验证更新/合并。
同样奇怪的是,它会在更新时验证字段名称是否为空值 - 它会抛出不同的异常,但最初的原因是 ConstraingViolationException。
https://github.com/konczak/demo-skills-validation-issue/blob/master/src/test/java/com/example/demo/entity/PersonTest.java#L91 https://github.com/konczak/demo-skills-validation-issue/blob/master/src/test/java/com/example/demo/entity/PersonTest.java#L91
在这种情况下我遗漏或误解了什么?