[hibernate-commits] Hibernate SVN: r16474 - in core/trunk/annotations: src/main/java/org/hibernate/cfg and 3 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Apr 29 08:25:30 EDT 2009


Author: epbernard
Date: 2009-04-29 08:25:30 -0400 (Wed, 29 Apr 2009)
New Revision: 16474

Added:
   core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/
   core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java
   core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java
   core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationAutoTest.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationDisabledTest.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationGroupsTest.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/CupHolder.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/Strict.java
Modified:
   core/trunk/annotations/pom.xml
   core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
Log:
ANN-827 add initial support for Bean Validation

Modified: core/trunk/annotations/pom.xml
===================================================================
--- core/trunk/annotations/pom.xml	2009-04-29 08:32:41 UTC (rev 16473)
+++ core/trunk/annotations/pom.xml	2009-04-29 12:25:30 UTC (rev 16474)
@@ -71,7 +71,16 @@
             <artifactId>cglib</artifactId>
             <scope>test</scope>
         </dependency>
-
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-validator</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <dependencyManagement>
@@ -97,10 +106,20 @@
                 <version>3.4.GA</version>
             </dependency>
             <dependency>
-            <groupId>cglib</groupId>
-            <artifactId>cglib</artifactId>
-            <version>2.2</version>
-        </dependency>
+                <groupId>cglib</groupId>
+                <artifactId>cglib</artifactId>
+                <version>2.2</version>
+            </dependency>
+            <dependency>
+                <groupId>org.hibernate</groupId>
+                <artifactId>hibernate-validator</artifactId>
+                <version>4.0.0.Beta1</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.validation</groupId>
+                <artifactId>validation-api</artifactId>
+                <version>1.0.CR2</version>
+            </dependency>
 
         </dependencies>
     </dependencyManagement>

Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java	2009-04-29 08:32:41 UTC (rev 16473)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -69,6 +69,7 @@
 import org.hibernate.annotations.common.reflection.java.JavaReflectionManager;
 import org.hibernate.cfg.annotations.Version;
 import org.hibernate.cfg.annotations.reflection.JPAMetadataProvider;
+import org.hibernate.cfg.beanvalidation.BeanValidationActivator;
 import org.hibernate.engine.NamedQueryDefinition;
 import org.hibernate.engine.NamedSQLQueryDefinition;
 import org.hibernate.engine.ResultSetMappingDefinition;
@@ -800,6 +801,13 @@
 	}
 
 	public SessionFactory buildSessionFactory() throws HibernateException {
+		enableLegacyHibernateValidator();
+		enableBeanValidation();
+		enableHibernateSearch(); 
+		return super.buildSessionFactory();
+	}
+
+	private void enableLegacyHibernateValidator() {
 		//add validator events if the jar is available
 		boolean enableValidatorListeners = !"false".equalsIgnoreCase( getProperty( "hibernate.validator.autoregister_listeners" ) );
 		Class validateEventListenerClass = null;
@@ -868,12 +876,12 @@
 				}
 			}
 		}
-		
-		enableHibernateSearch(); 
-		
-		return super.buildSessionFactory();
 	}
 
+	private void enableBeanValidation() {
+		BeanValidationActivator.activateBeanValidation( getEventListeners(), getProperties() );
+	}
+
 	/**
 	 * Tries to automatically register Hibernate Search event listeners by locating the 
 	 * appropriate bootstrap class and calling the <code>enableHibernateSearch</code> method.

Added: core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java	                        (rev 0)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationActivator.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -0,0 +1,87 @@
+package org.hibernate.cfg.beanvalidation;
+
+import java.util.Map;
+import java.util.Properties;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.HibernateException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.event.EventListeners;
+
+/**
+ * This class has no hard depenmdency on Bean Validation APIs
+ * It must uses reflectione very time BV is required.
+ * @author Emmanuel Bernard
+ */
+public class BeanValidationActivator {
+
+	private static final String BV_DISCOVERY_CLASS = "javax.validation.Validation";
+	private static final String TYPE_SAFE_ACTIVATOR_CLASS = "org.hibernate.cfg.beanvalidation.TypeSafeActivator";
+	private static final String TYPE_SAFE_ACTIVATOR_METHOD = "activateBeanValidation";
+	private static final String MODE_PROPERTY = "javax.persistence.validation.mode";
+
+	public static void activateBeanValidation(EventListeners eventListeners, Properties properties) {
+		ValidationMode mode = ValidationMode.getMode( properties.get( MODE_PROPERTY ) );
+		if (mode == ValidationMode.NONE) return;
+		try {
+			//load Validation
+			ReflectHelper.classForName( BV_DISCOVERY_CLASS, BeanValidationActivator.class );
+		}
+		catch ( ClassNotFoundException e ) {
+
+			if (mode == ValidationMode.CALLBACK) {
+				throw new HibernateException( "Bean Validation not available in the class path but required in " + MODE_PROPERTY );
+			}
+			else if (mode == ValidationMode.AUTO) {
+				//nothing to activate
+				return;
+			}
+			else {
+				throw new AssertionFailure( "Unexpected ValidationMode: " + mode );
+			}
+		}
+		try {
+			Class<?> activator = ReflectHelper.classForName( TYPE_SAFE_ACTIVATOR_CLASS, BeanValidationActivator.class );
+			Method buildDefaultValidatorFactory =
+					activator.getMethod( TYPE_SAFE_ACTIVATOR_METHOD, EventListeners.class, Properties.class );
+			buildDefaultValidatorFactory.invoke( null, eventListeners, properties );
+		}
+		catch ( NoSuchMethodException e ) {
+			throw new HibernateException( "Unable to get the default Bean Validation factory", e);
+		}
+		catch ( IllegalAccessException e ) {
+			throw new HibernateException( "Unable to get the default Bean Validation factory", e);
+		}
+		catch ( InvocationTargetException e ) {
+			throw new HibernateException( "Unable to get the default Bean Validation factory", e);
+		}
+		catch ( ClassNotFoundException e ) {
+			throw new HibernateException( "Unable to get the default Bean Validation factory", e);
+		}
+	}
+
+	private static enum ValidationMode {
+		AUTO,
+		CALLBACK,
+		NONE;
+
+		public static ValidationMode getMode(Object modeProperty) {
+			if (modeProperty == null) {
+				return AUTO;
+			}
+			else {
+				try {
+					return valueOf( modeProperty.toString().toUpperCase() );
+				}
+				catch ( IllegalArgumentException e ) {
+					throw new HibernateException( "Unknown validation mode in " + MODE_PROPERTY + ": " + modeProperty.toString() );
+				}
+			}
+		}
+	}
+}

Added: core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java	                        (rev 0)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/BeanValidationEventListener.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -0,0 +1,156 @@
+package org.hibernate.cfg.beanvalidation;
+
+import java.util.Set;
+import java.util.Properties;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import javax.validation.ValidatorFactory;
+import javax.validation.ConstraintViolation;
+import javax.validation.TraversableResolver;
+import javax.validation.Validator;
+import javax.validation.ConstraintViolationException;
+import javax.validation.groups.Default;
+
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.PreUpdateEventListener;
+import org.hibernate.event.PreDeleteEventListener;
+import org.hibernate.event.PreInsertEvent;
+import org.hibernate.event.PreUpdateEvent;
+import org.hibernate.event.PreDeleteEvent;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+//FIXME review exception model
+public class BeanValidationEventListener implements
+		PreInsertEventListener, PreUpdateEventListener, PreDeleteEventListener {
+	private static final String JPA_GROUP_PREFIX = "javax.persistence.validation.group.";
+	private static final Class<?>[] DEFAULT_GROUPS = new Class<?>[] { Default.class };
+	private static final Class<?>[] EMPTY_GROUPS = new Class<?>[] { };
+
+	private ValidatorFactory factory;
+	private TraversableResolver tr;
+	private Map<Operation, Class<?>[]> groupsPerOperation = new HashMap<Operation, Class<?>[]>(3);
+
+
+	public BeanValidationEventListener(ValidatorFactory factory, Properties properties) {
+		this.factory = factory;
+		setGroupsForOperation( Operation.INSERT, properties );
+		setGroupsForOperation( Operation.UPDATE, properties );
+		setGroupsForOperation( Operation.DELETE, properties );
+	}
+
+	private void setGroupsForOperation(Operation operation, Properties properties) {
+		Object property = properties.get( JPA_GROUP_PREFIX + operation.getGroupPropertyName() );
+
+		Class<?>[] groups;
+		if ( property == null ) {
+			groups = operation == Operation.DELETE ? EMPTY_GROUPS : DEFAULT_GROUPS;
+		}
+		else {
+			if ( property instanceof String ) {
+				String stringProperty = (String) property;
+				String[] groupNames = stringProperty.split( "," );
+				if ( groupNames.length == 1 && groupNames[0].equals( "" ) ) {
+					groups = EMPTY_GROUPS;
+				}
+				else {
+					List<Class<?>> groupsList = new ArrayList<Class<?>>(groupNames.length);
+					for (String groupName : groupNames) {
+						String cleanedGroupName = groupName.trim();
+						if ( cleanedGroupName.length() > 0) {
+							try {
+								groupsList.add( ReflectHelper.classForName( cleanedGroupName ) );
+							}
+							catch ( ClassNotFoundException e ) {
+								throw new HibernateException( "Unable to load class " + cleanedGroupName, e );
+							}
+						}
+
+					}
+					groups = groupsList.toArray( new Class<?>[groupsList.size()] );
+				}
+			}
+			else if ( property instanceof Class<?>[] ) {
+				groups = (Class<?>[]) property;
+			}
+			else {
+				//null is bad and excluded by instanceof => exception is raised
+				throw new HibernateException( JPA_GROUP_PREFIX + operation.getGroupPropertyName() + " is of unknown type: String or Class<?>[] only");
+			}
+		}
+		groupsPerOperation.put( operation, groups );
+	}
+
+	public boolean onPreInsert(PreInsertEvent event) {
+		validate( event.getEntity(), event.getSession().getEntityMode(), Operation.INSERT );
+		return false;
+	}
+
+	public boolean onPreUpdate(PreUpdateEvent event) {
+		validate( event.getEntity(), event.getSession().getEntityMode(), Operation.UPDATE );
+		return false;
+	}
+
+	public boolean onPreDelete(PreDeleteEvent event) {
+		validate( event.getEntity(), event.getSession().getEntityMode(), Operation.DELETE );
+		return false;
+	}
+
+	private <T> void validate(T object, EntityMode mode, Operation operation) {
+		if ( object == null || mode != EntityMode.POJO ) return;
+		Validator validator = factory.usingContext()
+										//.traversableResolver( tr )
+										.getValidator();
+		final Class<?>[] groups = groupsPerOperation.get( operation );
+		if ( groups.length > 0 ) {
+			final Set<ConstraintViolation<T>> constraintViolations =
+					validator.validate( object, groups );
+			//FIXME CV should no longer be generics
+			Object unsafeViolations = constraintViolations;
+			if (constraintViolations.size() > 0 ) {
+				//FIXME add Set<ConstraintViolation<?>>
+				throw new ConstraintViolationException(
+						"Invalid object at " + operation.getName() + " time for groups " + toString( groups ),
+						(Set<ConstraintViolation>) unsafeViolations);
+			}
+		}
+	}
+
+	private String toString(Class<?>[] groups) {
+		StringBuilder toString = new StringBuilder( "[");
+		for ( Class<?> group : groups ) {
+			toString.append( group.getName() ).append( ", " );
+		}
+		toString.append( "]" );
+		return toString.toString();
+	}
+
+	private static enum Operation {
+		INSERT("persist", "pre-persist"),
+		UPDATE("update", "pre-update"),
+		DELETE("remove", "pre-remove");
+
+		private String exposedName;
+		private String groupPropertyName;
+
+		Operation(String exposedName, String groupProperty) {
+			this.exposedName = exposedName;
+			this.groupPropertyName = groupProperty;
+		}
+
+		public String getName() {
+			return exposedName;
+		}
+
+		public String getGroupPropertyName() {
+			return groupPropertyName;
+		}
+	}
+
+}

Added: core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java	                        (rev 0)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/beanvalidation/TypeSafeActivator.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -0,0 +1,79 @@
+package org.hibernate.cfg.beanvalidation;
+
+import java.util.Map;
+import java.util.Arrays;
+import java.util.Properties;
+import javax.validation.ValidatorFactory;
+import javax.validation.Validation;
+
+import org.hibernate.HibernateException;
+import org.hibernate.event.EventListeners;
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.PreUpdateEventListener;
+import org.hibernate.event.PreDeleteEventListener;
+
+/**
+ * @author Emmanuel Bernard
+ */
+class TypeSafeActivator {
+
+	private static final String FACTORY_PROPERTY = "javax.persistence.validation.factory";
+
+	public static void activateBeanValidation(EventListeners eventListeners, Properties properties) {
+		ValidatorFactory factory = getValidatorFactory( properties );
+		BeanValidationEventListener beanValidationEventListener = new BeanValidationEventListener( factory, properties );
+
+		{
+			PreInsertEventListener[] listeners = eventListeners.getPreInsertEventListeners();
+			int length = listeners.length + 1;
+			PreInsertEventListener[] newListeners = new PreInsertEventListener[length];
+			System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+			newListeners[length - 1] = beanValidationEventListener;
+			eventListeners.setPreInsertEventListeners( newListeners );
+		}
+
+		{
+			PreUpdateEventListener[] listeners = eventListeners.getPreUpdateEventListeners();
+			int length = listeners.length + 1;
+			PreUpdateEventListener[] newListeners = new PreUpdateEventListener[length];
+			System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+			newListeners[length - 1] = beanValidationEventListener;
+			eventListeners.setPreUpdateEventListeners( newListeners );
+		}
+
+		{
+			PreDeleteEventListener[] listeners = eventListeners.getPreDeleteEventListeners();
+			int length = listeners.length + 1;
+			PreDeleteEventListener[] newListeners = new PreDeleteEventListener[length];
+			System.arraycopy( listeners, 0, newListeners, 0, length - 1 );
+			newListeners[length - 1] = beanValidationEventListener;
+			eventListeners.setPreDeleteEventListeners( newListeners );
+		}
+	}
+
+	static ValidatorFactory getValidatorFactory(Map<Object, Object> properties) {
+		ValidatorFactory factory = null;
+		if ( properties != null ) {
+			Object unsafeProperty = properties.get( FACTORY_PROPERTY );
+			if (unsafeProperty != null) {
+				try {
+					factory = ValidatorFactory.class.cast( unsafeProperty );
+				}
+				catch ( ClassCastException e ) {
+					throw new HibernateException( "Property " + FACTORY_PROPERTY
+							+ " should containt an object of type " + ValidatorFactory.class.getName() );
+				}
+			}
+		}
+		if (factory == null) {
+			try {
+				factory = Validation.buildDefaultValidatorFactory();
+			}
+			catch ( Exception e ) {
+				throw new HibernateException( "Unable to build the default ValidatorFactory", e);
+			}
+		}
+		return factory;
+	}
+
+}

Added: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationAutoTest.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationAutoTest.java	                        (rev 0)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationAutoTest.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -0,0 +1,36 @@
+package org.hibernate.test.annotations.beanvalidation;
+
+import java.math.BigDecimal;
+import javax.validation.ConstraintViolationException;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.test.annotations.TestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class BeanValidationAutoTest extends TestCase {
+	public void testListeners() {
+		CupHolder ch = new CupHolder();
+		ch.setRadius( new BigDecimal( "12" ) );
+		Session s = openSession(  );
+		Transaction tx = s.beginTransaction();
+		try {
+			s.persist( ch );
+			s.flush();
+			fail("invalid object should not be persisted");
+		}
+		catch ( ConstraintViolationException e ) {
+			assertEquals( 1, e.getConstraintViolations().size() );
+		}
+		tx.rollback();
+		s.close();
+	}
+
+	protected Class<?>[] getMappings() {
+		return new Class<?>[] {
+				CupHolder.class
+		};
+	}
+}

Added: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationDisabledTest.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationDisabledTest.java	                        (rev 0)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationDisabledTest.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -0,0 +1,42 @@
+package org.hibernate.test.annotations.beanvalidation;
+
+import java.math.BigDecimal;
+import javax.validation.ConstraintViolationException;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.test.annotations.TestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class BeanValidationDisabledTest extends TestCase {
+	public void testListeners() {
+		CupHolder ch = new CupHolder();
+		ch.setRadius( new BigDecimal( "12" ) );
+		Session s = openSession(  );
+		Transaction tx = s.beginTransaction();
+		try {
+			s.persist( ch );
+			s.flush();
+		}
+		catch ( ConstraintViolationException e ) {
+			fail("invalid object should not be validated");
+		}
+		tx.rollback();
+		s.close();
+	}
+
+	@Override
+	protected void configure(Configuration cfg) {
+		super.configure( cfg );
+		cfg.setProperty( "javax.persistence.validation.mode", "none" );
+	}
+
+	protected Class<?>[] getMappings() {
+		return new Class<?>[] {
+				CupHolder.class
+		};
+	}
+}
\ No newline at end of file

Added: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationGroupsTest.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationGroupsTest.java	                        (rev 0)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/BeanValidationGroupsTest.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -0,0 +1,68 @@
+package org.hibernate.test.annotations.beanvalidation;
+
+import java.math.BigDecimal;
+import javax.validation.ConstraintViolationException;
+import javax.validation.constraints.NotNull;
+import javax.validation.groups.Default;
+
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.annotations.reflection.XMLContext;
+import org.hibernate.test.annotations.TestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class BeanValidationGroupsTest extends TestCase {
+	public void testListeners() {
+		CupHolder ch = new CupHolder();
+		ch.setRadius( new BigDecimal( "12" ) );
+		Session s = openSession(  );
+		Transaction tx = s.beginTransaction();
+		try {
+			s.persist( ch );
+			s.flush();
+		}
+		catch ( ConstraintViolationException e ) {
+			fail("invalid object should not be validated");
+		}
+		try {
+			ch.setRadius( null );
+			s.flush();
+		}
+		catch ( ConstraintViolationException e ) {
+			fail("invalid object should not be validated");
+		}
+		try {
+			s.delete( ch );
+			s.flush();
+			fail("invalid object should not be persisted");
+		}
+		catch ( ConstraintViolationException e ) {
+			assertEquals( 1, e.getConstraintViolations().size() );
+			assertEquals( NotNull.class,
+						e.getConstraintViolations().iterator().next().getConstraintDescriptor().getAnnotation().annotationType()
+					);
+		}
+		tx.rollback();
+		s.close();
+	}
+
+	@Override
+	protected void configure(Configuration cfg) {
+		super.configure( cfg );
+		cfg.setProperty( "javax.persistence.validation.group.pre-persist",
+				"" );
+		cfg.setProperty( "javax.persistence.validation.group.pre-update",
+				"" );
+		cfg.setProperty( "javax.persistence.validation.group.pre-remove",
+				Default.class.getName() + ", " + Strict.class.getName() );
+	}
+
+	protected Class<?>[] getMappings() {
+		return new Class<?>[] {
+				CupHolder.class
+		};
+	}
+}
\ No newline at end of file

Added: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/CupHolder.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/CupHolder.java	                        (rev 0)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/CupHolder.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -0,0 +1,37 @@
+package org.hibernate.test.annotations.beanvalidation;
+
+import java.math.BigDecimal;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class CupHolder {
+	@Id
+	@GeneratedValue
+	private Integer id;
+	private BigDecimal radius;
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	@Max( value = 10, message = "Radius way out")
+	@NotNull(groups = Strict.class)
+	public BigDecimal getRadius() {
+		return radius;
+	}
+
+	public void setRadius(BigDecimal radius) {
+		this.radius = radius;
+	}
+}

Added: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/Strict.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/Strict.java	                        (rev 0)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/beanvalidation/Strict.java	2009-04-29 12:25:30 UTC (rev 16474)
@@ -0,0 +1,7 @@
+package org.hibernate.test.annotations.beanvalidation;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public interface Strict {
+}




More information about the hibernate-commits mailing list