如何使用JPA验证模型数据?

时间:2014-02-19 08:01:05

标签: java validation jpa eclipselink

我正在尝试让JPA验证工作,但似乎忽略了验证注释。我在SO JPA Entity Validation上找到了这个JPA验证示例,但它对我不起作用。 @NotNull@Size注释似乎被忽略了。

如上所述,我只使用两个类:

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-validator添加到pom.xml(没有效果)

2 个答案:

答案 0 :(得分: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>

并将validation属性设置为AUTO,这必须在persistence.xml中启用

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

或者以进步方式进行。

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

答案 1 :(得分:3)

您是否在类路径上有验证程序的运行时实现?通常人们似乎使用hibernate validator。 (例如确实通过将hibernate-validator添加到你的pom.xml中)

编辑:您的EclipseLink版本看起来也很旧,应该是JPA2实现。如果它是JPA1实现,您应该注册自己的事件监听器,这将是一个更多的工作。您可以在eclipse docs中找到一些提示(向下滚动到JPA部分),但看起来您必须稍微编辑标准验证器才能使其正常工作。 This blog可能会有所帮助。