diff --git a/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Address.java b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Address.java
new file mode 100644
index 000000000..f1484277e
--- /dev/null
+++ b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Address.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.integration.validation;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.Transient;
+import javax.validation.constraints.NotNull;
+
+@Entity(name="VAddress")
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public class Address implements IAddress, Serializable {
+ @Transient
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ @Basic
+ @NotNull
+ private String streetAddress;
+
+ @Basic
+ @NotNull
+ private String city;
+
+ @Basic
+ @NotNull
+ private String state;
+
+ @Basic
+ @NotNull
+ private String postalCode;
+
+ @Basic
+ private String phoneNumber;
+
+ public void setStreetAddress(String streetAddress) {
+ this.streetAddress = streetAddress;
+ }
+
+ public String getStreetAddress() {
+ return this.streetAddress;
+ }
+
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getCity() {
+ return this.city;
+ }
+
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getState() {
+ return this.state;
+ }
+
+
+ public void setPostalCode(String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getPostalCode() {
+ return this.postalCode;
+ }
+
+
+ public void setPhoneNumber(String phoneNumber) {
+ this.phoneNumber = phoneNumber;
+ }
+
+ public String getPhoneNumber() {
+ return this.phoneNumber;
+ }
+
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getId() {
+ return this.id;
+ }
+}
diff --git a/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/ConstraintNull.java b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/ConstraintNull.java
new file mode 100644
index 000000000..5b9fbba06
--- /dev/null
+++ b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/ConstraintNull.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.integration.validation;
+
+import java.io.Serializable;
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Null;
+
+@Entity(name = "VNULL")
+@Table(name = "NULL_ENTITY")
+public class ConstraintNull implements Serializable {
+
+ @Transient
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ @Basic
+ @Null
+ private String nullRequired;
+
+ @Basic
+ @NotNull
+ private String nullInvalid;
+
+
+ /*
+ * Some helper methods to create the entities to test with
+ */
+ public static ConstraintNull createInvalidNotNull() {
+ ConstraintNull c = new ConstraintNull();
+ return c;
+ }
+
+ public static ConstraintNull createInvalidNull() {
+ ConstraintNull c = new ConstraintNull();
+ c.setNullInvalid("not null");
+ c.setNullRequired("not null");
+ return c;
+ }
+
+ public static ConstraintNull createValid() {
+ ConstraintNull c = new ConstraintNull();
+ c.setNullInvalid("not null");
+ c.setNullRequired(null);
+ return c;
+ }
+
+
+ /*
+ * Main entity code
+ */
+ public ConstraintNull() {
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String getNullRequired() {
+ return nullRequired;
+ }
+
+ public void setNullRequired(String s) {
+ nullRequired = s;
+ }
+
+ public String getNullInvalid() {
+ return nullInvalid;
+ }
+
+ public void setNullInvalid(String s) {
+ nullInvalid = s;
+ }
+
+}
diff --git a/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Customer.java b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Customer.java
new file mode 100644
index 000000000..ea4561fea
--- /dev/null
+++ b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Customer.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.integration.validation;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.OneToOne;
+import javax.persistence.Transient;
+
+@Entity(name="VCustomer")
+public class Customer extends Person implements ICustomer, Serializable {
+ @Transient
+ private static final long serialVersionUID = 1L;
+
+ @OneToOne(fetch=FetchType.LAZY)
+ private Address shippingAddress;
+
+ @OneToOne(fetch=FetchType.LAZY)
+ private Address billingAddress;
+
+
+ public void setShippingAddress(IAddress shippingAddress) {
+ this.shippingAddress = (Address) shippingAddress;
+ }
+
+ public IAddress getShippingAddress() {
+ return this.shippingAddress;
+ }
+
+
+ public void setBillingAddress(IAddress billingAddress) {
+ this.billingAddress = (Address) billingAddress;
+ }
+
+ public IAddress getBillingAddress() {
+ return this.billingAddress;
+ }
+}
diff --git a/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/IAddress.java b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/IAddress.java
new file mode 100644
index 000000000..07747c4cd
--- /dev/null
+++ b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/IAddress.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.integration.validation;
+
+public interface IAddress {
+
+ public void setStreetAddress(String streetAddress);
+ public String getStreetAddress();
+
+ public void setCity(String city);
+ public String getCity();
+
+ public void setState(String state);
+ public String getState();
+
+ public void setPostalCode(String postalCode);
+ public String getPostalCode();
+
+ public void setPhoneNumber(String phoneNumber);
+ public String getPhoneNumber();
+}
diff --git a/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/ICustomer.java b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/ICustomer.java
new file mode 100644
index 000000000..728c9583b
--- /dev/null
+++ b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/ICustomer.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.integration.validation;
+
+import java.util.*;
+
+public interface ICustomer extends IPerson {
+
+ public void setShippingAddress(IAddress shippingAddress);
+ public IAddress getShippingAddress();
+
+ public void setBillingAddress(IAddress billingAddress);
+ public IAddress getBillingAddress();
+}
diff --git a/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/IPerson.java b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/IPerson.java
new file mode 100644
index 000000000..18abbe82a
--- /dev/null
+++ b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/IPerson.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.integration.validation;
+
+public interface IPerson {
+
+ public void setFirstName(String firstName);
+ public String getFirstName();
+
+ public void setLastName(String lastName);
+ public String getLastName();
+
+ public void setHomeAddress(IAddress homeAddress);
+ public IAddress getHomeAddress();
+}
diff --git a/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Person.java b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Person.java
new file mode 100644
index 000000000..606c71b64
--- /dev/null
+++ b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/Person.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.integration.validation;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToOne;
+import javax.persistence.Transient;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
+@Entity(name="VPerson")
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+public abstract class Person implements IPerson, Serializable {
+ @Transient
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ @Basic
+ @NotNull
+ private String firstName;
+
+ @Basic
+ @NotNull
+ private String lastName;
+
+ @OneToOne
+ @Valid
+ @NotNull
+ private Address homeAddress;
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getFirstName() {
+ return this.firstName;
+ }
+
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getLastName() {
+ return this.lastName;
+ }
+
+
+ public void setHomeAddress(IAddress homeAddress) {
+ this.homeAddress = (Address) homeAddress;
+ }
+
+ public IAddress getHomeAddress() {
+ return this.homeAddress;
+ }
+
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getId() {
+ return this.id;
+ }
+
+}
diff --git a/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestConstraints.java b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestConstraints.java
new file mode 100644
index 000000000..18513f5f2
--- /dev/null
+++ b/openjpa-integration/validation/src/test/java/org/apache/openjpa/integration/validation/TestConstraints.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
+ * or agreed to in writing, software distributed under the License is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.apache.openjpa.integration.validation;
+
+import javax.persistence.ValidationMode;
+
+import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.lib.log.Log;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
+import org.apache.openjpa.persistence.test.AllowFailure;
+import org.apache.openjpa.persistence.test.SingleEMFTestCase;
+
+/**
+ * Tests the new Bean Validation constraint support in the JPA 2.0 spec by
+ * focusing on the following Validation scenarios:
+ * 1) Test @Null constraint exception on variables in mode=AUTO
+ * 2) Test @NotNull constraint exception on variables in mode=AUTO
+ * 3) Test no constraint exception when mode=NONE
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestConstraints extends SingleEMFTestCase {
+
+ @Override
+ public void setUp() {
+ super.setUp(CLEAR_TABLES, ConstraintNull.class);
+ }
+
+ /**
+ * Scenario being tested:
+ * 1) Test @Null constraint exception on variables in mode=AUTO
+ */
+ public void testNullConstraint() {
+ getLog().trace("testNullConstraint() started");
+ // create EM from default EMF
+ OpenJPAEntityManager em = emf.createEntityManager();
+ assertNotNull(em);
+ try {
+ // verify Validation Mode
+ OpenJPAConfiguration conf = em.getConfiguration();
+ assertNotNull(conf);
+ assertTrue("ValidationMode",
+ conf.getValidationMode().equalsIgnoreCase("AUTO"));
+ // create invalid ConstraintNull instance
+ em.getTransaction().begin();
+ ConstraintNull c = ConstraintNull.createInvalidNull();
+ em.persist(c);
+ em.getTransaction().commit();
+ getLog().trace("testNullConstraint() failed");
+ fail("Expected a Validation exception");
+ } catch (Exception e) {
+ // expected
+ getLog().trace("Caught expected exception = " + e);
+ getLog().trace("testNullConstraint() passed");
+ } finally {
+ if ((em != null) && em.isOpen()) {
+ em.close();
+ }
+ }
+ }
+
+ /**
+ * Scenario being tested:
+ * 2) Test @NotNull constraint exception on variables in mode=AUTO
+ */
+ public void testNotNullConstraint() {
+ getLog().trace("testNotNullConstraint() started");
+ // create EM from default EMF
+ OpenJPAEntityManager em = emf.createEntityManager();
+ assertNotNull(em);
+ try {
+ // verify Validation Mode
+ OpenJPAConfiguration conf = em.getConfiguration();
+ assertNotNull(conf);
+ assertTrue("ValidationMode",
+ conf.getValidationMode().equalsIgnoreCase("AUTO"));
+ // create invalid ConstraintNull instance
+ em.getTransaction().begin();
+ ConstraintNull c = ConstraintNull.createInvalidNotNull();
+ em.persist(c);
+ em.getTransaction().commit();
+ getLog().trace("testNotNullConstraint() failed");
+ fail("Expected a Validation exception");
+ } catch (Exception e) {
+ // expected
+ getLog().trace("Caught expected exception = " + e);
+ getLog().trace("testNotNullConstraint() passed");
+ } finally {
+ if ((em != null) && em.isOpen()) {
+ em.close();
+ }
+ }
+ }
+
+ /**
+ * Scenario being tested:
+ * 3) Test no constraint exception when mode=NONE
+ */
+ public void testNullConstraintIgnored() {
+ getLog().trace("testNullConstraintIgnored() started");
+ // create our EMF w/ props
+ OpenJPAEntityManagerFactory emf = OpenJPAPersistence
+ .createEntityManagerFactory(
+ "null-none-mode",
+ "org/apache/openjpa/integration/validation/persistence.xml");
+ assertNotNull(emf);
+ // create EM
+ OpenJPAEntityManager em = emf.createEntityManager();
+ assertNotNull(em);
+ try {
+ // verify Validation Mode
+ OpenJPAConfiguration conf = em.getConfiguration();
+ assertNotNull(conf);
+ assertTrue("ValidationMode",
+ conf.getValidationMode().equalsIgnoreCase("NONE"));
+ // create invalid ConstraintNull instance
+ em.getTransaction().begin();
+ ConstraintNull c = ConstraintNull.createInvalidNull();
+ em.persist(c);
+ em.getTransaction().commit();
+ getLog().trace("testNullConstraintIgnored() passed");
+ } catch (Exception e) {
+ // unexpected
+ getLog().trace("testNullConstraintIgnored() failed");
+ fail("Unexpected Validation exception = " + e);
+ } finally {
+ if ((em != null) && em.isOpen()) {
+ em.close();
+ }
+ }
+ }
+
+
+ /**
+ * Internal convenience method for getting the OpenJPA logger
+ *
+ * @return
+ */
+ private Log getLog() {
+ return emf.getConfiguration().getLog("Tests");
+ }
+}
diff --git a/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml b/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml
index 9385e8c78..8a6d1ccca 100644
--- a/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml
+++ b/openjpa-integration/validation/src/test/resources/org/apache/openjpa/integration/validation/persistence.xml
@@ -40,4 +40,9 @@
NONE
+
+ org.apache.openjpa.integration.validation.ConstraintNull
+ NONE
+
+