2014-02-19 15 views
5

Ich versuche, JPA-Validierung zu arbeiten, aber es scheint, dass die Validierung Anmerkungen ignoriert werden. Ich fand dieses Beispiel der JPA-Validierung auf SO: JPA Entity Validation, aber es funktioniert nicht für mich. Die @NotNull und @Size Anmerkungen scheinen ignoriert zu werden.So validieren Sie Modelldaten mit JPA?

Wie in der Antwort oben erwähnte ich verwenden nur zwei Klassen:

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> 

Der Test schlägt fehl am fail(...) so wird die Ausnahme nie geworfen.

Wie kann ich (irgendwelche) Validierungsarbeit mit JPA machen? Ich kann Hibernate oder Spring nicht verwenden.

Vielen Dank für Ihre Hilfe

EDIT: hinzugefügt Hibernate-Validator pom.xml (ohne Wirkung)

+0

Sie haben nur die Validierungs-API implementiert, aber keine Implementierung. Überprüfen Sie den @wds 'Link und kopieren Sie das Teil mit auf Ihre pom.xml –

+0

Bitte beachten Sie den ersten Kommentar auf @wds Antwort – svenhuebner

+0

Ich habe gesehen, aber es scheint nicht, dass Sie gemacht, was ich gesagt habe (Ihre pom.xml zeigt das) ... –

Antwort

4

Fügen Sie dies Ihren pom.xmls hinzu.

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

Und gesetzt Validierung Eigenschaft auf AUTO muss dies in persistence.xml

<property name="javax.persistence.validation.mode" value="AUTO" /> 

Oder aktivieren sein progrmatically es.

final Set<ConstraintViolation<Object>> errors = validator.validate(object, classes); 
+0

Das hat funktioniert. Vielen Dank. Ich musste die Überprüfungseigenschaft nicht auf AUTO setzen. – svenhuebner

+0

Nachtrag: Ich musste auch die eclipselink-Version (jetzt mit 2.5.0) aktualisieren, wie von @wds vorgeschlagen. Mit der Version 1.2.0 bekam ich eine ValidationException HV000041, wann immer etwas validiert wurde. – svenhuebner

+0

Seien Sie vorsichtig, wenn Sie den automatischen Modus für [Hibernate Validator] verwenden (https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/additionalmodules.html#d0e3900): "AUTO: * if * Bean Die Validierung ist im Klassenpfad vorhanden ". Setzen Sie es lieber auf CALLBACK, um einen Fehler zu erhalten, wenn kein Validator im Klassenpfad gefunden wird. –

3

Haben Sie eine Laufzeitimplementierung des Prüfers auf Ihrem Classpath haben? Typischerweise scheinen die Leute hibernate validator zu verwenden. (z. B. durch Hinzufügen von Hibernate-Validator zu Ihrer pom.xml)

edit: Ihre Version von EclipseLink sieht auch ziemlich alt aus, es sollte eine JPA2-Implementierung sein. Wenn es sich um eine JPA1-Implementierung handelt, sollten Sie Ihren eigenen Ereignis-Listener registrieren, was ein wenig mehr Arbeit bedeutet. Sie können einige Hinweise in der eclipse docs finden (scrollen Sie nach unten zu JPA Abschnitt), aber es sieht so aus, als müssten Sie die Standard-Validatoren etwas bearbeiten, damit es funktioniert. This blog könnte hilfreich sein.

+0

Wenn Sie damit meinen, eine Abhängigkeit vom Hibernate-Validator in meiner pom.xml zu haben, habe ich das ohne Wirkung versucht. Wenn du das nicht gemeint hättest, könntest du bitte etwas genauer sein? Ich bin neu in der ganzen JavaEE/JPA/Maven-Umgebung. – svenhuebner

+0

@svenhuebner Das war in der Tat was ich meinte. Ich habe oben ein paar andere mögliche Täter gefunden. – wds

Verwandte Themen