2014-02-19 35 views
5

我試圖讓JPA驗證工作,但似乎忽略了驗證註釋。我在SO上發現了JPA驗證的這個例子:JPA Entity Validation,但它對我不起作用。註釋@NotNull@Size似乎被忽略。如何使用JPA驗證模型數據?

正如上述回答我提到的只用了兩個類:

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> 

測試失敗在fail(...)所以異常被拋出從來沒有。

如何使用JPA進行(任何)驗證工作?我不能使用Hibernate或Spring。

謝謝您的幫助

編輯:添加的Hibernate驗證器的pom.xml(無效果)

+0

您只包含驗證API,但沒有實現。檢查@wds的鏈接,並將複製到你的pom.xml –

+0

請看第一條評論@wds的回答 – svenhuebner

+0

我已經看到了,但似乎並不像你說的那樣(你的pom.xml顯示)... –

回答

4

添加到您的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> 

並設置驗證屬性爲AUTO這必須是能在persistence.xml中

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

或者做progrmatically。

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

這工作。非常感謝你。我不必將驗證屬性設置爲AUTO。 – svenhuebner

+0

附錄:我還必須按照@wds的建議更新eclipselink版本(現在使用2.5.0)。在版本1.2.0中,每當有事件被驗證時,我都會得到一個ValidationException HV000041。 – svenhuebner

+0

對[hibernate驗證器]使用自動模式時要小心(https://docs.jboss.org/hibernate/stable/annotations/reference/en/html/additionalmodules.html#d0e3900):「AUTO:* if * Bean驗證存在於類路徑中「。在類路徑中找不到驗證程序時,最好將其設置爲CALLBACK以獲取錯誤。 –

3

你有沒有驗證的你的類路徑運行時實現?通常人們似乎使用hibernate validator。 (例如,通過在您的pom.xml中添加休眠驗證程序)

編輯:您的EclipseLink版本也看起來很舊,它應該是JPA2實現。如果它是一個JPA1實現,你應該註冊你自己的事件監聽器,這將是一個更多的工作。您可以在eclipse docs(向下滾動到JPA部分)中找到一些提示,但看起來您必須稍微編輯標準驗證器才能使其工作。 This blog可能會有所幫助。

+0

如果你的意思是在我的pom.xml中有一個依賴於hibernate-validator的東西,我試過了,沒有任何效果。如果這不是你的意思,你能不能更具體一點?我對整個JavaEE/JPA/maven環境是新手。 – svenhuebner

+0

@svenhuebner這確實是我的意思。我已經提出了其他一些可能的罪魁禍首。 – wds