Spring JPA不会在更新时验证bean

时间:2017-10-20 14:04:15

标签: java spring hibernate spring-boot spring-validator

我正在使用Spring Boot 1.5.7,Spring JPA,Hibernate验证,Spring Data REST,Spring HATEOAS。

我有一个这样简单的bean:

@Entity
public class Person {
    @Id
    @GeneratedValue
    private Long id;

    @NotBlank
    private String name;
}

正如您所看到的,我正在使用@NotBlank。根据Hibernate文档,验证应该在pre-persist和pre-update上进行。

我创建了一个junit测试:

@Test(expected = ConstraintViolationException.class)
public void saveWithEmptyNameThrowsException() {  
    Person person = new Person();
    person.setName("");
    personRepository.save(person);
}

此测试工作正常,因此验证过程正确进行。相反,在此测试用例中,验证不起作用:

@Test(expected = ConstraintViolationException.class)
public void saveWithEmptyNameThrowsException() {
   Person person = new Person();
   person.setName("Name");
   personRepository.save(person);

   person.setName("");
   personRepository.save(person);
}

我发现了另一个similar question,但遗憾的是没有任何回复。 为什么不在update()方法上进行验证?建议解决问题?

2 个答案:

答案 0 :(得分:3)

我认为没有发生ConstraintViolationException,因为在更新期间Hibernate不会在现场将结果刷新到数据库。尝试用saveAndFlush()替换你的测试save()。

答案 1 :(得分:0)

您使用的是Spring Boot JPA测试吗?如果是,则saveWithEmptyNameThrowsException被包装在事务中,并且在方法执行完成之前不会提交。换句话说,该方法被视为一个工作单元。调用personRepository.save(除非启用自动提交/刷新更改)将不会求助于实体更改的反映,而是在提交事务之前。这是您测试的解决方法:

@Test(expected = ConstraintViolationException.class)
public void saveWithEmptyNameThrowsException() {
   // Wrap the following into another transaction
   // begin
      Person person = new Person();
      person.setName("Name");
      personRepository.save(person);
   // commit

   // Wrap the following into another transaction
   // begin
      person = ... get from persistence context
      person.setName("");
      personRepository.save(person);
   // commit
}

您可以在Spring中使用TransactionTemplate进行程序化事务划分。