代码之家  ›  专栏  ›  技术社区  ›  drenda

Spring JPA不会在更新时验证bean

  •  6
  • drenda  · 技术社区  · 7 年前

    我使用的是Spring Boot 1.5.7、Spring JPA、Hibernate验证、Spring Data REST和Spring HATEOAS。

    我有这样一个简单的豆子:

    @Entity
    public class Person {
        @Id
        @GeneratedValue
        private Long id;
    
        @NotBlank
        private String name;
    }
    

    正如你所见,我正在使用@NotBlank。根据Hibernate文档,应该在预持久和预更新上进行验证。

    我创建了一个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 但不幸的是,没有任何回复。

    2 回复  |  直到 7 年前
        1
  •  4
  •   Yurii Kozachok    7 年前

    我认为ConstraintViolationException不会发生,因为在更新过程中Hibernate不会将结果即时刷新到数据库。尝试将测试中的save()替换为saveAndFlush()。

        2
  •  0
  •   Warren Nocos    7 年前

    你在使用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
    }
    

    您可以使用 TransactionTemplate 用于Spring中的编程事务划分。