Ok, I'm trying to setup an application in a Java EE Container. I use JPA for persistence and I also use the javax.validation.constraints.*
constraints. By default the container validate the entities during the @PrePersist
and @PreUpdate
lifecycle events and it's good for me, but how do I handle the ConstraintViolationException
?
I can't find any docs on it, any suggestion is welcomed.
Data validation is a common task that occurs in all layers of an application, including persistence. The Java™ Persistence API (JPA) 2.0 provides support for the Bean Validation API so that data validation can be done at run time.
You can use @PrePersist Callback event in your entity to valdiate the email before saving it to database. Or you can make a setter method in your Entity and validate the data in setter method. Show activity on this post. You can create a custom constraint.
Very basically, Bean Validation works by defining constraints to the fields of a class by annotating them with certain annotations.
The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.
Well, you could catch it :) Here is an example (from a unit test):
public class CustomerTest {
private static EntityManagerFactory emf;
private EntityManager em;
@BeforeClass
public static void createEntityManagerFactory() {
emf = Persistence.createEntityManagerFactory("MyPu");
}
@AfterClass
public static void closeEntityManagerFactory() {
emf.close();
}
@Before
public void beginTransaction() {
em = emf.createEntityManager();
em.getTransaction().begin();
}
@After
public void rollbackTransaction() {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (em.isOpen()) {
em.close();
}
}
@Test
public void nameTooShort() {
try {
Customer customer = new Customer("Bo");
em.persist(customer);
em.flush();
fail("Expected ConstraintViolationException wasn't thrown.");
} catch (ConstraintViolationException e) {
assertEquals(1, e.getConstraintViolations().size());
ConstraintViolation<?> violation = e.getConstraintViolations().iterator().next();
assertEquals("name", violation.getPropertyPath().toString());
assertEquals(Size.class, violation.getConstraintDescriptor().getAnnotation().annotationType());
}
}
}
Where my Customer looks like:
@Entity
public class Customer {
@Id @GeneratedValue
@NotNull
private Long id;
@NotNull
@Size(min = 3, max = 80)
private String name;
private boolean archived;
...
}
But this was just an example to show a tiny part of the API.
In my opinion, you should actually handle the validation at the view level. Many presentation frameworks support Bean Validation: JSF 2.0, Wicket, Spring MVC...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With