Domain Class Validation
Example
class User {
String login
String password
static constraints = {
login(size:5..15,blank:false,unique:true)
password(size:5..15,blank:false)
}
}
In the reference that follows, className.propertyName.validationConstraint refers to the error message codes defined in grails-app/i18n/message.properties.
For example, referring to the above class, the error message might be defined as:
user.login.blank=Please enter a login
Since 0.5. You could use common pattern "className.propertyName.constraintName.error" for all constraints, example: "user.login.blank.error=Please enter a login".
Validation Constraint Reference
blank
Usage: set to false if a string value cannot be blank
Note: an empty form field will appear in the request parameters as an empty string, not as null. Keep this in mind when setting domain fields directly form request parameters
Example:
login(blank:false)
Error message code: className.propertyName.blank
creditCard
Usage: set to true if a string should be a credit card number
Example:
cardNumber(creditCard:true)
Error message code: className.propertyName.creditCard.invalid
Usage: set to true if a string value is an email address
Example:
contactEmail(email:true)
Error message code: className.propertyName.email.invalid
inList
Usage: constrains a value so that it must be contained within the given list
Example:
name(inList:["Joe", "Fred", "Bob"] )
Error message code: className.propertyName.not.inList
This constraint influences schema generation.
length
Deprecated in 0.4. Removed in 0.5. Use size instead.
Usage: Uses a Groovy range to restrict the length of a string or array
Example:
login(length:5..15)
Error message code: className.propertyName.length.toolong, className.propertyName.length.tooshort
This constraint influences schema generation.
matches
Usage: Applies a regular expression against a string value
Example:
login(matches:"[a-zA-Z]+")
Error message code: className.propertyName.matches.invalid
max
Usage: sets the maximum value of a class that implements java.lang.Comparable. The same type needs to be used as the property itself.
Example:
age(max:new Date())
price(max:999F)
Error message code: className.propertyName.max.exceeded
This constraint influences schema generation.
maxLength
Deprecated in 0.4. Removed in 0.5. Use maxSize instead.
Usage: sets the maximum length of a string or array property
Example:
login(maxLength:5)
Error message code: className.propertyName.maxLength.exceeded
This constraint influences schema generation.
maxSize
Usage: sets the maximum size of a collection or number property
Deprecated in 0.5 for number properties. Use max instead
Example:
children(maxSize:25)
Error message code: className.propertyName.maxSize.exceeded
This constraint influences schema generation.
min
Usage: sets the minimum value of a class that implements java.lang.Comparable. The same type needs to be used as the property itself.
Example:
age(min:new Date())
price(min:0F)
Error message code: className.propertyName.min.notmet
This constraint influences schema generation.
minLength
Deprecated in 0.4. Removed in 0.5. Use minSize instead.
Usage: sets the minimum length of a string or array property
Example:
login(minLength:5)
Error message code: className.propertyName.minLength.notmet
This constraint influences schema generation.
minSize
Usage: sets the minimum size of a collection or number property
Deprecated in 0.5 for number properties. Use min instead
Example:
children(minSize:5)
Error message code: className.propertyName.minSize.notmet
This constraint influences schema generation.
notEqual
Usage: validates that a property is not equal to the specified value
Example:
login(notEqual:"Bob")
Error message code: className.propertyName.notEqual
nullable
Usage: set to false if the property value cannot be null
Note: an empty form field will appear in the request parameters as an empty string, not as null. Keep this in mind when setting domain fields directly form request parameters
Example:
age(nullable:false)
Error message code: className.propertyName.nullable
range
Usage: Uses a Groovy range to ensure that a property's value occurs within a specified range
Example:
age(range:minAge..maxAge)
Error message code: className.propertyName.range.toosmall or className.propertyName.range.toobig
This constraint influences schema generation.
scale
Since: 0.4
Usage: Set to the desired scale for floating point numbers (i.e., the number of digits to the right of the decimal point). This constraint is applicable for properties of the following types: java.lang.Float, java.lang.Double, and java.math.BigDecimal (and its subclasses). When validation is invoked, this constraint determines if the number includes more nonzero decimal places than the scale permits. If so, it automatically rounds the number to the maximum number of decimal places allowed by the scale. This constraint does not generate validation error messages.
Example:
salary(scale:2)
Error message code: N/A
This constraint influences schema generation.
size
Usage: Uses a Groovy range to restrict the size of a collection or number or the length of a String
Deprecated in 0.5 for number properties. Use range instead
Example:
children(size:5..15)
Note: currently it could not be used in addition to blank:true or nullable:true contraints, a custom validator may be added to perform this kind of constraints (if not null then...)
Error message code: className.propertyName.size.toosmall or className.propertyName.size.toobig
This constraint influences schema generation.
unique
Usage: set to true if the property must be unique (this is a persistent call and will query the database)
Example:
login(unique:true)
Note: be aware that it's possible (though uncommon in practice) for a uniqueness constraint validation to pass but a subsequent save of the data to fail due to a uniqueness constraint enforced at the database level. The only way to prevent this would be to use the SERIALIZABLE transaction isolation level (bad for performance) or just be prepared to get an exception to this effect at some point.
[Since 0.5] Scope of unique constraint can be specified. "Scope" - is a name of another property of the same class, or list of such names. Semantic in these cases is: pair of constrained property value and scope property value must be unique (or combination of constrained property value and all scope property values must be unique).
Example:
group(unique:'department')
In the above example group name must be unique in one department but there might be groups with same name in different departments.
Another example:
login(unique:['group','department'])
In this example login must be unique in group and department. There might be same logins in different groups or different departments.
Error message code: className.propertyName.unique
url
Usage: set to true if a string value is a URL address
Example:
homePage(url:true)
Error message code: className.propertyName.url.invalid
validator
Usage: set to a Closure to use custom validation. A single or no parameter Closure receives the value, a two-parameter Closure receives the value and object reference.
Since 0.5.5 a three-parameter Closure receives the value, object reference and the errors object.
The closure can return:
- null or true to indicate that the value is valid
- false to indicate an invalid value and use the default message code
- a string to indicate the error code to append to the "classname.propertName." string to display an error
- a list containing a string as above, and then any number of arguments following it, which can be used as formatted message arguments indexed at 3 onwards. See grails-app/i18n/message.properties to see how the default error message codes use the arguments.
If the closure is a three-parameter closure the return value is ignored and the closure is expected to populate the errors object.
Examples:
even( validator: {
return (it % 2) == 0
})
password1( validator: {
val, obj ->
obj.properties['password2'] == val
})
magicNumber( validator:
someClosureWithTwoParameters)
// This one assumes you have an error message defined like:
// classname.propertyName.custom.error=My error shows arguments {3} and {4} for value {0}
otherProperty( validator: { return ['custom.error', arg1, arg2] } )
// The following example does not use custom validation.
// A custom message may be defined in messages.properties:
// user.login.blank=Please enter a login
// which will be used instead of default.blank.message
class User {
String login
static constraints = {
login(blank:false)
}
}
// In the following example, custom validation is used:
// user.login.validator.invalid=Please enter a login
class User {
String login
static constraints = {
login(validator: {
return (it.length != 0)
})
}
}
// The following might define the error message as:
// user.login.invalid.bountyhunter=Invalid bounty hunter ({2}) tried to log in. (Class name = {1}. Property name = {0})
class User {
String login
static constraints = {
login(validator: {
if (!it.startsWith('boba')) return ['invalid.bountyhunter']
})
}
}
Error message code (default): className.propertyName.validator.invalid

