How to validate model data with JPA?
eclipselink, java, jpa, validation
Solution
Add this to your pom.xmls.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
<exclusions>
<exclusion>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
And set validation property to AUTO this must to be enable in persistence.xml
<property name="javax.persistence.validation.mode" value="AUTO" />
Or do it progrmatically.
final Set<ConstraintViolation<Object>> errors = validator.validate(object, classes);
Problem
I am trying to get JPA validation to work, however it seems that the validation annotations are ignored. I found this example of JPA validation on SO: JPA Entity Validation, but it does not work for me. The `@NotNull` and `@Size` annotations seem to be ignored. As in the answer mentioned above I use only two classes: Customer.java: ``` package com.validation.test; import javax.persistence.*; import javax.validation.constraints.*; @Entity @Table(name = "T_CUSTOMER") public class Customer { @Id @NotNull @SequenceGenerator(name = "customerIdSeq", sequenceName = "T_CUSTOMER_ID_SEQ", allocationSize = 1) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "customerIdSeq") private Long id; @NotNull @Size(min = 3, max = 80) private String name; public Customer() {}; public Customer(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` CustomerTest.java: ``` package com.validation.test.test; import static org.junit.Assert.*; import javax.persistence.*; import javax.validation.*; import javax.validation.constraints.Size; import org.junit.*; import com.validation.test.Customer; public class CustomerTest { private static EntityManagerFactory emf; private EntityManager em; @BeforeClass public static void createEntityManagerFactory() { emf = Persistence.createEntityManagerFactory("testPU"); } @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()); } } } ``` pom.xml: ``` <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.validation.test</groupId> <artifactId>test</artifactId> <version>0.0.1-SNAPSHOT</version> <repositories> <repository> <id>maven2-repository.java.net</id> <name>Java.net Repository for Maven</name> <url>http://download.java.net/maven/2/</url> <layout>default</layout> </repository> </repositories> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>javax.persistence</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc5</artifactId> <version>11.2.0.2.0</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.0.0.GA</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.0.3.Final</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>wwd-bs</finalName> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.16</version> </plugin> </plugins> </pluginManagement> </build> </project> ``` persistence.xml: ``` <?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"> <persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>com.validation.test.Customer</class> <properties> <property name="eclipselink.logging.level" value="FINE" /> <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" /> <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:orcl" /> <property name="javax.persistence.jdbc.user" value="user" /> <property name="javax.persistence.jdbc.password" value="password" /> <property name="eclipselink.logging.level" value="INFO" /> </properties> </persistence-unit> </persistence> ``` The test fails at the `fail(...)` so the exception is never thrown. How can I make (any) validation work with JPA? I cannot use Hibernate or Spring. Thank you for your help EDIT: added hibernate-validator to pom.xml (with no effect)