Index: ../jpa/deployers/pom.xml
===================================================================
--- ../jpa/deployers/pom.xml	(revision 88339)
+++ ../jpa/deployers/pom.xml	Mon Sep 14 20:16:10 CEST 2009
@@ -22,6 +22,7 @@
   </properties>
 
   <dependencies>
+    <!-- Test dependencies -->
     <!-- For 'mocking' a TransactionManager we use JBossTS -->
     <dependency>
       <groupId>jboss.jbossts</groupId>
@@ -44,10 +45,24 @@
     </dependency>
     <dependency>
       <groupId>org.hibernate</groupId>
+      <artifactId>hibernate-validator</artifactId>
+      <version>4.0.0.CR1</version>
+      <scope>test</scope>
+    </dependency>
+
+
+    <!-- regular dependencies -->
+    <dependency>
+      <groupId>org.hibernate</groupId>
       <artifactId>hibernate-entitymanager</artifactId>
-      <version>3.4.0.GA</version>
+      <version>3.5.0.Beta-1</version>
     </dependency>
     <dependency>
+      <groupId>javax.validation</groupId>
+      <artifactId>validation-api</artifactId>
+      <version>1.0.CR5</version>
+    </dependency>
+    <dependency>
       <groupId>org.jboss.integration</groupId>
       <artifactId>jboss-transaction-spi</artifactId>
       <version>5.0.3.GA</version>
@@ -72,7 +87,14 @@
       <groupId>org.jboss.metadata</groupId>
       <artifactId>jboss-metadata</artifactId>
       <version>1.0.0.CR17</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.hibernate</groupId>
+          <artifactId>ejb3-persistence</artifactId>
+        </exclusion>
+      </exclusions>
     </dependency>
+
     <!-- For @JMX -->
     <dependency>
       <groupId>org.jboss.microcontainer</groupId>
Index: ../jpa/sandbox/src/main/java/org/jboss/jpa/sandbox/remote/RemotelyInjectEntityManagerFactory.java
===================================================================
--- ../jpa/sandbox/src/main/java/org/jboss/jpa/sandbox/remote/RemotelyInjectEntityManagerFactory.java	(revision 78333)
+++ ../jpa/sandbox/src/main/java/org/jboss/jpa/sandbox/remote/RemotelyInjectEntityManagerFactory.java	Mon Sep 14 20:17:49 CEST 2009
@@ -33,22 +33,32 @@
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.HashMap;
 
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import javax.persistence.Cache;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.criteria.QueryBuilder;
 import javax.persistence.spi.PersistenceProvider;
 import javax.persistence.spi.PersistenceUnitTransactionType;
+import javax.validation.ValidatorFactory;
+import javax.validation.Validation;
 
 import org.hibernate.ejb.HibernatePersistence;
 import org.jboss.jpa.deployment.PersistenceUnitInfoImpl;
+import org.jboss.jpa.sandbox.JPAConstants;
 import org.jboss.logging.Logger;
 import org.jboss.metadata.jpa.spec.PersistenceUnitMetaData;
 import org.jboss.metadata.jpa.spec.TransactionType;
 
 /**
  * @author <a href="mailto:cdewolf@redhat.com">Carlo de Wolf</a>
+ * @author Emmanuel Bernard
+ * 
  * @version $Revision: $
  */
 public class RemotelyInjectEntityManagerFactory implements EntityManagerFactory, Serializable
@@ -79,6 +89,28 @@
       throw new RuntimeException("NYI");
    }
 
+   //public JPA contract
+   //For the protected method formerly called #getProperties, see #getMetadataProperties
+   public Map<String, Object> getProperties()
+   {
+      return actualFactory.getProperties();
+   }
+
+   public Set<String> getSupportedProperties()
+   {
+      return actualFactory.getSupportedProperties();
+   }
+
+   public Cache getCache()
+   {
+      return actualFactory.getCache();
+   }
+
+   public PersistenceUnitUtil getPersistenceUnitUtil()
+   {
+      return actualFactory.getPersistenceUnitUtil();
+   }
+
    private void createEntityManagerFactory() throws Exception
    {
       Properties props = new Properties();
@@ -94,7 +126,7 @@
       pi.setJarFiles(jarFiles);
       pi.setPersistenceProviderClassName(HibernatePersistence.class.getName());
       log.debug("Found persistence.xml file in EJB3 jar");
-      props.putAll(getProperties());
+      props.putAll(getMetadataProperties());
       pi.setManagedClassnames(safeList(metaData.getClasses()));
       pi.setPersistenceUnitName(metaData.getName());
       pi.setMappingFileNames(safeList(metaData.getMappingFiles()));
@@ -179,9 +211,16 @@
       */
       
       PersistenceProvider pp = (PersistenceProvider) providerClass.newInstance();
+      Map<Object, Object> properties = new HashMap<Object, Object>(1);
+      properties.put( JPAConstants.BEAN_VALIDATION_FACTORY, getValidatorFactory() );
       actualFactory = pp.createContainerEntityManagerFactory(pi, null);      
    }
-   
+
+   private ValidatorFactory getValidatorFactory() {
+      //FIXME get it from JNDI or the deployer
+      return Validation.buildDefaultValidatorFactory();
+   }
+   
    public EntityManager createEntityManager()
    {
       return actualFactory.createEntityManager();
@@ -192,6 +231,16 @@
       return actualFactory.createEntityManager(map);
    }
 
+   public QueryBuilder getQueryBuilder()
+   {
+      return actualFactory.getQueryBuilder();
+   }
+
+   public Metamodel getMetamodel()
+   {
+      return actualFactory.getMetamodel();
+   }
+
    protected String getJaccContextId()
    {
       //return di.getSimpleName();
@@ -243,7 +292,7 @@
       */
    }
    
-   protected Map<String, String> getProperties()
+   protected Map<String, String> getMetadataProperties()
    {
       Map<String, String> properties = metaData.getProperties();
       return (properties != null) ? properties : Collections.<String, String>emptyMap();
Index: ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/validation/BeanValidationTestCase.java
===================================================================
--- ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/validation/BeanValidationTestCase.java	Mon Sep 14 20:30:25 CEST 2009
+++ ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/validation/BeanValidationTestCase.java	Mon Sep 14 20:30:25 CEST 2009
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jpa.deployers.test.validation;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertEquals;
+
+import javax.naming.InitialContext;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceException;
+import javax.transaction.TransactionManager;
+import javax.validation.ValidationException;
+import javax.validation.ConstraintViolationException;
+
+import org.jboss.jpa.deployers.test.common.PersistenceTestCase;
+import org.jboss.jpa.deployers.test.common.Person;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:cdewolf@redhat.com">Carlo de Wolf</a>
+ * @author <a href="mailto:proteus400@gmail.com">Matt C</a>
+ * @author Emmanuel Bernard
+ *
+ * @version $Revision: $
+ */
+public class BeanValidationTestCase extends PersistenceTestCase
+{
+   @BeforeClass
+   public static void beforeClass() throws Exception
+   {
+      PersistenceTestCase.beforeClass();
+      deploy(BeanValidationTestCase.class.getResource("/org/jboss/jpa/deployers/test/jndi"));
+   }
+
+   @Test
+   public void testEM() throws Exception
+   {
+      InitialContext ctx = new InitialContext();
+      TransactionManager tm = (TransactionManager) ctx.lookup("java:/TransactionManager");
+      EntityManager em = null;
+      try
+      {
+         em = (EntityManager) ctx.lookup("JndiEM");
+      }
+      catch(Exception e)
+      {
+         fail("EntityManager lookup test failed");
+      }
+      try
+      {
+         tm.begin();
+         try
+         {
+            Person p = new Person();
+            p.setName("Caroline");
+            p.setNickname("C"); //invalid nickname
+            em.persist(p);
+            em.flush();
+            fail("Bean validation should have been triggered");
+         }
+         //not sure of the spec forces a wrap or not
+         catch (ConstraintViolationException e) {
+            //success
+         }
+         catch (PersistenceException e) {
+            assertEquals("Should be a validation exception", e.getCause().getClass(), ConstraintViolationException.class);
+         }
+         finally
+         {
+            tm.rollback();
+         }
+      }
+      catch(Exception e)
+      {
+         fail("EntityManager invocation test failed");
+      }
+   }
+
+   @Test
+   public void testEMF() throws Exception
+   {
+      InitialContext ctx = new InitialContext();
+      EntityManagerFactory emf = null;
+      try
+      {
+         emf = (EntityManagerFactory) ctx.lookup("JndiEMF");
+      } catch(Exception e)
+      {
+         fail("EntityManagerFactory lookup test failed");
+      }
+      try
+      {
+         EntityManager em = emf.createEntityManager();
+         Person p = new Person();
+         p.setName("Debby");
+         em.persist(p);
+      }
+      catch(Exception e)
+      {
+         fail("EntityManagerFactory invocation test failed");
+      }
+   }
+}
\ No newline at end of file
Index: ../jpa/deployers/src/main/java/org/jboss/jpa/tx/TransactionScopedEntityManager.java
===================================================================
--- ../jpa/deployers/src/main/java/org/jboss/jpa/tx/TransactionScopedEntityManager.java	(revision 79921)
+++ ../jpa/deployers/src/main/java/org/jboss/jpa/tx/TransactionScopedEntityManager.java	Mon Sep 14 19:43:16 CEST 2009
@@ -25,12 +25,19 @@
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.util.Map;
+import java.util.Set;
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityTransaction;
 import javax.persistence.FlushModeType;
 import javax.persistence.LockModeType;
 import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.QueryBuilder;
 
 import org.hibernate.Session;
 import org.hibernate.ejb.HibernateEntityManager;
@@ -43,8 +50,12 @@
 
 /**
  * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
+ * @author Emmanuel Bernard
+ *
  * @version $Revision: 79921 $
  */
+//FIXME EBE: getProperies / setProperty does not play well with reusing the EM
+//FIXME EBE: is the TransactionScopedEntityManager made to be reused?
 public class TransactionScopedEntityManager implements EntityManager, Externalizable
 {
    private static final long serialVersionUID = 4260828563883650376L;
@@ -97,11 +108,21 @@
       getEntityManager().joinTransaction();
    }
 
+   public <T> T unwrap(Class<T> type)
+   {
+      return getEntityManager().unwrap(type);
+   }
+
    public void clear()
    {
       getEntityManager().clear();
    }
 
+   public void detach(Object entity)
+   {
+      getEntityManager().detach(entity);
+   }
+
    public FlushModeType getFlushMode()
    {
       return getEntityManager().getFlushMode();
@@ -113,6 +134,11 @@
       getEntityManager().lock(entity, lockMode);
    }
 
+   public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties)
+   {
+      getEntityManager().lock(entity, lockMode, properties);
+   }
+
    public <T> T getReference(Class<T> entityClass, Object primaryKey)
    {
       EntityManager em = getEntityManager();
@@ -139,6 +165,20 @@
       return em.createQuery(ejbqlString);
    }
 
+   public <T> TypedQuery<T> createQuery(CriteriaQuery<T> query)
+   {
+      EntityManager em = getEntityManager();
+      if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      return em.createQuery(query);
+   }
+
+   public <T> TypedQuery<T> createQuery(String query, Class<T> type)
+   {
+      EntityManager em = getEntityManager();
+      if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      return em.createQuery(query, type);
+   }
+
    public Query createNamedQuery(String name)
    {
       EntityManager em = getEntityManager();
@@ -146,6 +186,13 @@
       return em.createNamedQuery(name);
    }
 
+   public <T> TypedQuery<T> createNamedQuery(String query, Class<T> type)
+   {
+      EntityManager em = getEntityManager();
+      if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      return em.createQuery(query, type);
+   }
+
    public Query createNativeQuery(String sqlString)
    {
       EntityManager em = getEntityManager();
@@ -181,6 +228,48 @@
       }
    }
 
+   public <T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties)
+   {
+      EntityManager em = getEntityManager();
+      if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      try
+      {
+         return em.find(entityClass, primaryKey, properties);
+      }
+      finally
+      {
+         if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      }
+   }
+
+   public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockModeType)
+   {
+      EntityManager em = getEntityManager();
+      if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      try
+      {
+         return em.find(entityClass, primaryKey, lockModeType);
+      }
+      finally
+      {
+         if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      }
+   }
+
+   public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockModeType, Map<String, Object> properties)
+   {
+      EntityManager em = getEntityManager();
+      if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      try
+      {
+         return em.find(entityClass, primaryKey, lockModeType, properties);
+      }
+      finally
+      {
+         if (!factory.isInTx()) em.clear(); // em will be closed by interceptor
+      }
+   }
+
    public void persist(Object entity)
    {
       factory.verifyInTx();
@@ -190,7 +279,7 @@
    public <A> A merge(A entity)
    {
       factory.verifyInTx();
-      return (A) getEntityManager().merge(entity);
+      return getEntityManager().merge(entity);
    }
 
    public void remove(Object entity)
@@ -205,11 +294,50 @@
       getEntityManager().refresh(entity);
    }
 
+   public void refresh(Object entity, Map<String, Object> properties)
+   {
+      factory.verifyInTx();
+      getEntityManager().refresh(entity, properties);
+   }
+
+   public void refresh(Object entity, LockModeType lockModeType)
+   {
+      factory.verifyInTx();
+      getEntityManager().refresh(entity, lockModeType);
+   }
+
+   public void refresh(Object entity, LockModeType lockModeType, Map<String, Object> properties)
+   {
+      factory.verifyInTx();
+      getEntityManager().refresh(entity, lockModeType, properties);
+   }
+
    public boolean contains(Object entity)
    {
       return getEntityManager().contains(entity);
    }
 
+   public LockModeType getLockMode(Object entity)
+   {
+      factory.verifyInTx();
+      return getEntityManager().getLockMode(entity);
+   }
+
+   public void setProperty(String key, Object value)
+   {
+      getEntityManager().setProperty(key, value);
+   }
+
+   public Map<String, Object> getProperties()
+   {
+      return getEntityManager().getProperties();
+   }
+
+   public Set<String> getSupportedProperties()
+   {
+      return getEntityManager().getSupportedProperties();
+   }
+
    public void flush()
    {
       factory.verifyInTx();
@@ -230,7 +358,23 @@
    {
       throw new IllegalStateException("Illegal to call this method from injected, managed EntityManager");
    }
-   
+
+   public EntityManagerFactory getEntityManagerFactory()
+   {
+      //FIXME EBE: should we wrap the EMF?
+      return getEntityManager().getEntityManagerFactory();
+   }
+
+   public QueryBuilder getQueryBuilder()
+   {
+      return getEntityManager().getQueryBuilder();
+   }
+
+   public Metamodel getMetamodel()
+   {
+      return getEntityManager().getMetamodel();
+   }
+
    protected EntityManager getEntityManager()
    {
       /* legacy
Index: ../jpa/deployers/src/main/java/org/jboss/jpa/remote/RemotelyInjectEntityManagerFactory.java
===================================================================
--- ../jpa/deployers/src/main/java/org/jboss/jpa/remote/RemotelyInjectEntityManagerFactory.java	(revision 78416)
+++ ../jpa/deployers/src/main/java/org/jboss/jpa/remote/RemotelyInjectEntityManagerFactory.java	Mon Sep 14 20:16:10 CEST 2009
@@ -33,15 +33,23 @@
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.HashMap;
 
 import javax.naming.InitialContext;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import javax.persistence.Cache;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.criteria.QueryBuilder;
 import javax.persistence.spi.PersistenceProvider;
 import javax.persistence.spi.PersistenceUnitTransactionType;
+import javax.validation.ValidatorFactory;
+import javax.validation.Validation;
 
 import org.hibernate.ejb.HibernatePersistence;
 import org.jboss.jpa.deployment.PersistenceUnitInfoImpl;
+import org.jboss.jpa.JPAConstants;
 import org.jboss.logging.Logger;
 import org.jboss.metadata.jpa.spec.PersistenceUnitMetaData;
 import org.jboss.metadata.jpa.spec.TransactionType;
@@ -54,6 +62,7 @@
  * up JPA locally.
  * 
  * @author <a href="mailto:cdewolf@redhat.com">Carlo de Wolf</a>
+ * @author Emmanuel Bernard
  * @version $Revision: $
  */
 public class RemotelyInjectEntityManagerFactory implements EntityManagerFactory, Serializable
@@ -84,6 +93,13 @@
       throw new RuntimeException("NYI");
    }
 
+   //public JPA contract
+   //For the protected method formerly called #getProperties, see #getMetadataProperties
+   public Map<String, Object> getProperties()
+   {
+      return actualFactory.getProperties();
+   }
+
    private void createEntityManagerFactory() throws Exception
    {
       log.debug("Booting up the entity manager factory");
@@ -112,9 +128,16 @@
       */
       
       PersistenceProvider pp = (PersistenceProvider) providerClass.newInstance();
-      actualFactory = pp.createContainerEntityManagerFactory(pi, null);      
+      Map<Object, Object> properties = new HashMap<Object, Object>(1);
+      properties.put( JPAConstants.BEAN_VALIDATION_FACTORY, getValidatorFactory() );
+      actualFactory = pp.createContainerEntityManagerFactory(pi, properties);      
    }
-   
+
+   private ValidatorFactory getValidatorFactory() {
+      //FIXME get it from JNDI or the deployer
+      return Validation.buildDefaultValidatorFactory();
+   }
+   
    public EntityManager createEntityManager()
    {
       return actualFactory.createEntityManager();
@@ -125,6 +148,16 @@
       return actualFactory.createEntityManager(map);
    }
 
+   public QueryBuilder getQueryBuilder()
+   {
+      return actualFactory.getQueryBuilder();
+   }
+
+   public Metamodel getMetamodel()
+   {
+      return actualFactory.getMetamodel();
+   }
+
    protected String getJaccContextId()
    {
       //return di.getSimpleName();
@@ -176,12 +209,27 @@
       */
    }
    
-   protected Map<String, String> getProperties()
+   protected Map<String, String> getMetadataProperties()
    {
       Map<String, String> properties = metaData.getProperties();
       return (properties != null) ? properties : Collections.<String, String>emptyMap();
    }
 
+   public Set<String> getSupportedProperties()
+   {
+      return actualFactory.getSupportedProperties();
+   }
+
+   public Cache getCache()
+   {
+      return actualFactory.getCache();
+   }
+
+   public PersistenceUnitUtil getPersistenceUnitUtil()
+   {
+      return actualFactory.getPersistenceUnitUtil();
+   }
+
    public boolean isOpen()
    {
       throw new RuntimeException("NYI");
Index: ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/common/MockRegionFactory.java
===================================================================
--- ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/common/MockRegionFactory.java	(revision 79754)
+++ ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/common/MockRegionFactory.java	Mon Sep 14 20:03:09 CEST 2009
@@ -140,6 +140,11 @@
          // no-op
       }
 
+      public boolean contains(Object o)
+      {
+         return false;
+      }
+
       public long getElementCountInMemory()
       {
          return 0;
Index: ../jpa/deployers/src/main/java/org/jboss/jpa/injection/InjectedEntityManagerFactory.java
===================================================================
--- ../jpa/deployers/src/main/java/org/jboss/jpa/injection/InjectedEntityManagerFactory.java	(revision 79915)
+++ ../jpa/deployers/src/main/java/org/jboss/jpa/injection/InjectedEntityManagerFactory.java	Mon Sep 14 19:16:46 CEST 2009
@@ -26,9 +26,14 @@
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.util.Map;
+import java.util.Set;
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import javax.persistence.Cache;
+import javax.persistence.PersistenceUnitUtil;
+import javax.persistence.metamodel.Metamodel;
+import javax.persistence.criteria.QueryBuilder;
 
 import org.jboss.jpa.deployment.ManagedEntityManagerFactory;
 import org.jboss.jpa.tx.TransactionScopedEntityManager;
@@ -38,6 +43,8 @@
  * Comment
  *
  * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
+ * @author Emmanuel Bernard
+ *
  * @version $Revision: 79915 $
  */
 public class InjectedEntityManagerFactory implements EntityManagerFactory, Externalizable
@@ -87,7 +94,17 @@
       return delegate.createEntityManager(map);
    }
 
+   public QueryBuilder getQueryBuilder()
+   {
+      return delegate.getQueryBuilder();
+   }
 
+   public Metamodel getMetamodel()
+   {
+      return delegate.getMetamodel();
+   }
+
+
    public EntityManager getEntityManager()
    {
       return new TransactionScopedEntityManager(managedFactory);
@@ -98,6 +115,26 @@
       throw new IllegalStateException("It is illegal to close an injected EntityManagerFactory");
    }
 
+   public Map<String, Object> getProperties()
+   {
+      return delegate.getProperties();
+   }
+
+   public Set<String> getSupportedProperties()
+   {
+      return delegate.getSupportedProperties();
+   }
+
+   public Cache getCache()
+   {
+      return delegate.getCache();
+   }
+
+   public PersistenceUnitUtil getPersistenceUnitUtil()
+   {
+      return delegate.getPersistenceUnitUtil();
+   }
+
    public boolean isOpen()
    {
       return getDelegate().isOpen();
Index: ../jpa/sandbox/src/main/java/org/jboss/jpa/sandbox/JPAConstants.java
===================================================================
--- ../jpa/sandbox/src/main/java/org/jboss/jpa/sandbox/JPAConstants.java	Mon Sep 14 20:13:27 CEST 2009
+++ ../jpa/sandbox/src/main/java/org/jboss/jpa/sandbox/JPAConstants.java	Mon Sep 14 20:13:27 CEST 2009
@@ -0,0 +1,15 @@
+package org.jboss.jpa.sandbox;
+
+/**
+ * JPA constants
+ *
+ * @author Emmanuel Bernard
+ */
+public interface JPAConstants
+{
+   /**
+    * key the Bean Validation Factory should be placed in the property Map when
+    * initializing the EntityManagerFactory
+    */
+   public static final String BEAN_VALIDATION_FACTORY = "javax.persistence.validation.factory";
+}
\ No newline at end of file
Index: ../jpa/deployers/src/main/java/org/jboss/jpa/JPAConstants.java
===================================================================
--- ../jpa/deployers/src/main/java/org/jboss/jpa/JPAConstants.java	Mon Sep 14 20:10:49 CEST 2009
+++ ../jpa/deployers/src/main/java/org/jboss/jpa/JPAConstants.java	Mon Sep 14 20:10:49 CEST 2009
@@ -0,0 +1,15 @@
+package org.jboss.jpa;
+
+/**
+ * JPA constants
+ * 
+ * @author Emmanuel Bernard
+ */
+public interface JPAConstants
+{
+   /**
+    * key the Bean Validation Factory should be placed in the property Map when
+    * initializing the EntityManagerFactory
+    */
+   public static final String BEAN_VALIDATION_FACTORY = "javax.persistence.validation.factory";
+}
Index: ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/common/Person.java
===================================================================
--- ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/common/Person.java	(revision 79915)
+++ ../jpa/deployers/src/test/java/org/jboss/jpa/deployers/test/common/Person.java	Mon Sep 14 20:25:16 CEST 2009
@@ -23,6 +23,7 @@
 
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.validation.constraints.Size;
 
 /**
  * A generic entity with an id and a string for testing.
@@ -38,6 +39,8 @@
    
    private String name;
 
+   private String nickname;
+
    @Override
    public boolean equals(Object obj)
    {
@@ -87,4 +90,15 @@
    {
       this.name = name;
    }
+
+   @Size(min=2)
+   public String getNickname()
+   {
+      return nickname;
-}
+   }
+
+   public void setNickname(String nickname)
+   {
+      this.nickname = nickname;
+   }
+}
Index: ../jpa/deployers/src/main/java/org/jboss/jpa/deployment/PersistenceUnitInfoImpl.java
===================================================================
--- ../jpa/deployers/src/main/java/org/jboss/jpa/deployment/PersistenceUnitInfoImpl.java	(revision 78416)
+++ ../jpa/deployers/src/main/java/org/jboss/jpa/deployment/PersistenceUnitInfoImpl.java	Mon Sep 14 20:05:13 CEST 2009
@@ -34,6 +34,8 @@
 import javax.persistence.spi.ClassTransformer;
 import javax.persistence.spi.PersistenceUnitInfo;
 import javax.persistence.spi.PersistenceUnitTransactionType;
+import javax.persistence.Caching;
+import javax.persistence.ValidationMode;
 import javax.sql.DataSource;
 
 import org.hibernate.ejb.HibernatePersistence;
@@ -63,7 +65,11 @@
    private PersistenceUnitTransactionType transactionType;
    private URL persistenceUnitRootUrl;
    private boolean excludeClasses;
+   private ValidationMode validationMode;
+   private String schemaVersion;
+   private Caching caching;
 
+   //FIXME who uses that? Get rid of it and make attributes final
    public PersistenceUnitInfoImpl()
    {
    }
@@ -244,6 +250,12 @@
       return properties;
    }
 
+   public String PersistenceXMLSchemaVersion()
+   {
+      //FIXME when metadata is updated to JPA 2
+      return null;  //To change body of implemented methods use File | Settings | File Templates.
+   }
+
    protected static Map<String, String> getProperties(PersistenceUnitMetaData metaData)
    {
       Map<String, String> properties = metaData.getProperties();
@@ -290,6 +302,18 @@
       return excludeClasses;
    }
 
+   public Caching getCaching()
+   {
+      //FIXME when metadata is updated to JPA 2
+      return null;  //To change body of implemented methods use File | Settings | File Templates.
+   }
+
+   public ValidationMode getValidationMode()
+   {
+      //FIXME when metadata is updated to JPA 2
+      return null;  //To change body of implemented methods use File | Settings | File Templates.
+   }
+
    public void setExcludeUnlistedClasses(boolean excludeClasses)
    {
       this.excludeClasses = excludeClasses;
Index: ../jpa/deployers/src/main/java/org/jboss/jpa/deployment/PersistenceUnitDeployment.java
===================================================================
--- ../jpa/deployers/src/main/java/org/jboss/jpa/deployment/PersistenceUnitDeployment.java	(revision 84471)
+++ ../jpa/deployers/src/main/java/org/jboss/jpa/deployment/PersistenceUnitDeployment.java	Mon Sep 14 20:16:10 CEST 2009
@@ -30,12 +30,15 @@
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.HashMap;
 
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.spi.PersistenceProvider;
+import javax.validation.ValidatorFactory;
+import javax.validation.Validation;
 
 import org.hibernate.ejb.HibernatePersistence;
 import org.jboss.beans.metadata.api.annotations.Inject;
@@ -45,6 +48,7 @@
 import org.jboss.jpa.spi.PersistenceUnitRegistry;
 import org.jboss.jpa.spi.XPCResolver;
 import org.jboss.jpa.tx.TransactionScopedEntityManager;
+import org.jboss.jpa.JPAConstants;
 import org.jboss.logging.Logger;
 import org.jboss.metadata.jpa.spec.PersistenceUnitMetaData;
 import org.jboss.util.naming.NonSerializableFactory;
@@ -55,6 +59,8 @@
  * Comment
  *
  * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
+ * @author Emmanuel Bernard
+ *
  * @version $Revision: 84471 $
  */
 public class PersistenceUnitDeployment //extends AbstractJavaEEComponent
@@ -298,8 +304,11 @@
       }
       
       PersistenceProvider pp = (PersistenceProvider) providerClass.newInstance();
-      actualFactory = pp.createContainerEntityManagerFactory(pi, null);
 
+      Map<Object, Object> properties = new HashMap<Object, Object>(1);
+      properties.put( JPAConstants.BEAN_VALIDATION_FACTORY, getValidatorFactory() );
+      actualFactory = pp.createContainerEntityManagerFactory(pi, properties);
+
       managedFactory = new ManagedEntityManagerFactory(actualFactory, kernelName);
 
       String entityManagerJndiName = (String) props.get("jboss.entity.manager.jndi.name");
@@ -316,6 +325,11 @@
       }
    }
 
+   private ValidatorFactory getValidatorFactory() {
+      //FIXME get it from JNDI or the deployer
+      return Validation.buildDefaultValidatorFactory();
+   }
+
    public void stop() throws Exception
    {
       log.info("Stopping persistence unit " + kernelName);
Index: ../jpa/sandbox/pom.xml
===================================================================
--- ../jpa/sandbox/pom.xml	(revision 78234)
+++ ../jpa/sandbox/pom.xml	Mon Sep 14 20:16:10 CEST 2009
@@ -42,10 +42,22 @@
     </dependency>
     <dependency>
       <groupId>org.hibernate</groupId>
+      <artifactId>hibernate-validator</artifactId>
+      <version>4.0.0.CR1</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.hibernate</groupId>
       <artifactId>hibernate-entitymanager</artifactId>
-      <version>3.3.2.GA</version>
+      <version>3.5.0.Beta-1</version>
     </dependency>
     <dependency>
+      <groupId>javax.validation</groupId>
+      <artifactId>validation-api</artifactId>
+      <version>1.0.CR5</version>
+    </dependency>
+    <dependency>
       <groupId>org.jboss</groupId>
       <artifactId>jboss-transaction-spi</artifactId>
       <version>5.0.0.Beta4</version>
@@ -75,6 +87,12 @@
       <groupId>org.jboss.metadata</groupId>
       <artifactId>jboss-metadata</artifactId>
       <version>1.0.0.Beta26</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.hibernate</groupId>
+          <artifactId>ejb3-persistence</artifactId>
+        </exclusion>
+      </exclusions>
     </dependency>
     <dependency>
       <groupId>org.jboss.naming</groupId>
