简体   繁体   English

Spring JPA不会在更新时验证bean

[英]Spring JPA doesn't validate bean on update

I'm using Spring Boot 1.5.7, Spring JPA, Hibernate validation, Spring Data REST, Spring HATEOAS. 我正在使用Spring Boot 1.5.7,Spring JPA,Hibernate验证,Spring Data REST,Spring HATEOAS。

I've a simple bean like this: 我有一个像这样的简单bean:

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

    @NotBlank
    private String name;
}

As you can see I'm using @NotBlank. 如你所见,我正在使用@NotBlank。 According to Hibernate documentation the validation should be made on pre-persist and pre-update. 根据Hibernate文档,验证应该在pre-persist和pre-update上进行。

I created a junit test: 我创建了一个junit测试:

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

this test works fine and therefore the validation process happens correctly. 此测试工作正常,因此验证过程正确。 Instead in this test case, the validation doesn't work: 相反,在此测试用例中,验证不起作用:

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

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

I found another similar question but unfortunately there isn't any reply. 我发现了另一个类似的问题,但遗憾的是没有任何答复。 Why the validation is not made on update() method? 为什么不在update()方法上进行验证? Advice to solve the problem? 建议解决问题?

I think ConstraintViolationException is not occurred because during update Hibernate don't flush result to database on the spot. 我认为没有发生ConstraintViolationException,因为在更新期间Hibernate不会在现场将结果刷新到数据库。 Try to replace in your test save() with saveAndFlush(). 尝试使用saveAndFlush()替换测试save()。

Are you using Spring Boot JPA test? 你在使用Spring Boot JPA测试吗? If yes, saveWithEmptyNameThrowsException is wrapped within a transaction, and it will not be committed until the method's execution is done. 如果是,则saveWithEmptyNameThrowsException包含在事务中,并且在方法执行完成之前不会提交。 In other words, the method is treated as one unit of work. 换句话说,该方法被视为一个工作单元。 Calling personRepository.save (unless you enable auto commit/flush changes) will not resort to reflection of your entity changes, but until transaction is committed. 调用personRepository.save (除非启用自动提交/刷新更改)将不会求助于实体更改的反映,而是在提交事务之前。 Here's a workaround for your test: 以下是测试的解决方法:

@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
}

You can use TransactionTemplate for programmatic transaction demarcation in Spring. 您可以在Spring中使用TransactionTemplate进行编程事务划分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM