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
+ */
+@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 {
+}