2014-02-19 69 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