From release 2020.09 on Servoy has added/changed how validation is done for database data.

databaseManager has now a new method: JSValidationObject databaseManager.validate(record [, optionalState]);

Which is automatically called when saveData() is done for every record that was changed and will be saved to the database. But you can also call it manually your self to report possible validation problems.

It will return a JSValidationObject when the record has validation problems, if everything was ok then a null is returned.

The optionalState object can be anything that you want to pass on to all of the validators that are being called.

The validate(record) call will first call the new "onValidate" table event method which has the signature: (record, validationObject, stateObject).

If there is a problem that should be reported the JSValidationObject has a few report methods that you can use to report problems, the largest one has the signature: (message,dataprovider,level,customObject,messageKeyParams), only message is mandatory, the rest are optional.

After the "onValidate" table event, it will call one of the "onRecordUpdate" or "onRecordInsert" table event depending on if the record is an existing or new record. The signature of those table events are also changed: (record, validationObject, stateObject), so those are now the same as "onValidate". Instead of returning false or throwing an exception it is now better to just report problems on the validationObject and alwasy just return true. This way you control the message.

The 3rd step is to check if there are columns that are null or an empty string but the column is marked as not null. If the column has this problem it will be reported with the i18n key: servoy.record.error.null.not.allowed ("Dataprovider '{0}' can't be null or empty")

The 4th step is to check the size of the column, if a column has a value that won't fit into the database it will be reported by the i18n key: servoy.record.error.columnSizeTooSmall ("Column {0} is too small, max length can be {1}, value '{2}'")

The last step is calling all the Column Validation for all the changed columns of the record. By default Servoy will not call the column validators anymore when the value is set into the record, it will only validate the columns when saving or when the validate(record) method is called. This change of behavior is controlled by the servoy property "servoy.execute.column.validators.only.on.validate_and_save" which is default true. In the table editor column validation section there is now a check box that controls this property "Only execute validators on validate/save"

All the build in validators are changed to use the new way, this means for the GlobalMethodValidator that also there the signature is changed from just getting the value object to: (value, dataproviderid, validationObject, stateObject)

Also for this the same applies as from the "onRecordUpdate" instead of return false or throwing an Exception, the global method validator should report problems to the validationObject and always just return true.

All of the steps are called, even if one already fails, so the JSValidationObject can have multiply reported problems at once. When all the steps/checks are done and it has at least 1 problem reported then it will set itself on the JSRecord.validationObject property (which is cleared before any validate) and the validationObject will be returned.

If the caller of databaseManager.validate(record) sees that an object is returned it can then call validationObject.getProblems() to get an array of JSProblems. A JSProblem has has a number of fields:


var validatonObject = databaseManager.validate(record, {originationCall: "customerForm"});
if (validationObject)
{
   var problems = validationObject.getProblems();
   problems.forEach(/** @param {JSProblem} problem*/ function(problem) {
			application.output(problem.message)
			application.output(problem.i18NMessage);
			application.output(problem.column);
			application.output(problem.customObject);
		});
}


Besides the getProblems() the JSValidationObject has also some extra state, 2 boolean properties: onBeforeInsertFailed and onBeforeUpdateFailed those are filled in if the onRecordUpdate or Insert failed in a legacy way (returning false), here is also a getGenericExceptions() method that will return exception that could be happen in the validation code that are not directly record or column validation problems but more generic once like exceptions that are triggered when the onRecordUpdate or Insert did fail.