update
and insert
queries. As part of these two operations, a ManagedObject<T>
will ensure that its properties have valid values. For example, a Person
object might ensure that its name starts with a capital letter and that its phone number has only numeric values. If one or more validation fails, the update or insert operation will fail and the data is not sent to the database. A validation failure will throw a QueryException
that returns an HTTP response with error messaging to help the client correct their request.Validate
metadata to properties of a table definition. Here's an example of a validation that ensures a tweet is less than 140 characters:Validate
class. Here is an example:state
property must be one of the four listed strings. If a value other than one of those four strings is used, the error message returned to the HTTP client would be:Validate
and its named constructors for possible options.Validate
annotations on properties declared in a managed object subclass (transient properties) have no effect.Validate
to provide custom validation behavior. For example, if there were a ValidatePhoneNumber
class:Validate
must override Validate.validate()
and call the superclass' primary constructor when instantiated. Here's an example of that phone number validator:value
is doesn't meet the validation criteria, this method adds an error string to the ValidationContext
it is passed. Error messages should be brief and indicate the successful criteria that failed. Information about the property being validated will automatically be added to the error message, so you do not need to include that information. If the context has no errors at the end of validation, the validation succeeds; otherwise, it fails.ValidationContext
also has information about the property being validated, and whether the validation is running for an object being inserted or an object being updated.Validate
metadata. In this case, all of the validations for a property must pass. The order in which multiple validations are performed is undefined and subject to change. Here's an example of validations that ensure a property's value is 10 characters long and only contains 10 alphabetic capital letters:Query<T>
's insert
or update
method is invoked. A validator can be restricted to only run on insert
or update
by passing values for its optional constructor arguments onUpdate
and onInsert
:Person
with a name
and email
property and then inserted in a query where email
hasn't been set:email
was not set on Query.values
, validations will not be run on that property.Validate.present()
requires that the associated property must have a value. A property with this validator must be provided each time the object is inserted or updated. For example, the following declaration requires that email
is set on insertion, but doesn't have to be for updates:Validate.present()
is Validate.absent()
. This validation prevents a property from being set. This is useful when a value should be included during insertion, but can't be updated. Here's an example:canOnlyBeSetOnce
does not have a value. Because this validator is not run on insert operations, there is no restriction when the object is first inserted.null
for the property email
:Column.isNullable
property. Consider the following declaration:name
must not be null and must be greater than 10 characters long. The behavior of inserting or updating this property is shown in the following table.ManagedObject<T>
instances to be partially updated, which also allows for partial PUTs. Partial PUTs can be prevented by adding Validate.present()
metadata to all properties.Validate.validate()
is non-null.Validate
, you may override ManagedObject<T>.validate()
. This method is useful when a validation involves more than one property. Here's an example:super
implementation must be invoked to run validations managed by annotations. You must return the ValidationContext
created by the superclass' implementation.Query<T>.values
. Values set via Query<T>.valueMap
are not validated and is useful for inserting data without validation. Here's an example of skipping validation:ManagedObject<T>
subclasses may override willUpdate
and willInsert
to make changes prior to being updated or inserted. For example, a managed object may have updated and created dates that can be guaranteed to be set when inserted or updated:willUpdate
and willInsert
are run before any validation occurs. Like validations, willUpdate
and willInsert
are skipped when using Query.valueMap
.