I'm using Spring Boot 1.5.7, Spring JPA, Hibernate validation, Spring Data REST, Spring HATEOAS.
I've a simple bean like this:
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
@NotBlank
private String name;
}
As you can see I'm using @NotBlank. According to Hibernate documentation the validation should be made on pre-persist and pre-update.
I created a junit test:
@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? Advice to solve the problem?
I think ConstraintViolationException is not occurred because during update Hibernate don't flush result to database on the spot. Try to replace in your test save() with saveAndFlush().
Are you using Spring Boot JPA test? If yes, saveWithEmptyNameThrowsException
is wrapped within a transaction, and it will not be committed until the method's execution is done. 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. 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.