Skip to main content

Data Validations

Validations can be implemented in 2 locations:

  • In the data layer for simple validations
  • In the logic layer if the validation also requires access to other Components or other resources

In both layers, the create and modify methods have the custom-preCreate and custom-preModify anchors. We can use these anchors to validate all incoming values:

StarshipCruds.java
// anchor:custom-preCreate:start
CrudsResult<DataRef> licensePlateValidation = validateLicensePlate(details.getLicensePlate());
if (licensePlateValidation.getLicensePlate()) {
return licensePlateValidation;
}
// anchor:custom-preCreate:end

// anchor:custom-preModify:start
CrudsResult<DataRef> licensePlateValidation = validateLicensePlate(starshipDetails.getLicensePlate());
if (licensePlateValidation.getLicensePlate()) {
return licensePlateValidation;
}
// anchor:custom-preModify:end

Now creating an invalid Starship instance or making an invalid change will be rejected before any changes to the database are made.

Error Messages

However, we might also need a clear error message:

CrudsResult<DataRef> error = CrudsResult.error(
Diagnostic.error("space", "Starship", "space.starship.invalidLicensePlate")
);

Diagnostics represent error messages. They are defined with 3 parameters:

  1. component: the name of the component, space in this case
  2. element: the name of the element, Starship in this case
  3. key: a key that uniquely defines the error message you wish to propagate, the convention is to define it as {component}.{element}.{errorDescription} or {component}.{element}.{field}.{errorDescription}

There are also some helper classes that can be used to create cruds error with error messages.

// DiagnosticFactory can create diagnostics
DiagnosticFactory diagnosticFactory = new DiagnosticFactory("space","starship");
Diagnostic errorMsg = diagnosticFactory.error("space.starship.demoError");

// DiagnosticHelper can create crudsErrors with diagnostics
DiagnosticHelper diagnosticHelper = new DiagnosticHelper("space", "starship");
CrudsResult<DataRef> crudsError = diagnosticHelper.createCrudsError("space.starship.invalidLicensePlate");

// DiagnosticFieldFactory can be used to create diagnostics on field level
DiagnosticFieldFactory fieldFactory = diagnosticFactory.fieldFactory("licensePlate");
Diagnostic fieldErrorMsg = fieldFactory.error("rentWork.car.licensePlate.invalidLicensePlate");

Last, we need to add the translations of the errors to the translation properties files. There are 3 properties files for each Component, which can be found in the Control Layer:

  • {component}.properties
  • {component}_nl.properties
  • {component}_en.properties

In these files, there are custom-translations anchors to add any additional translations:

# anchor:custom-translations:start
space.starship.invalidLicensePlate=Not a valid licensePlate
# anchor:custom-translations:end
tip

You can also add additional translation files in the accompanying ext directory.

Options

Option
isRequired Field

Adds a validation that rejects any undefined values for this Field.

<options>
<isRequired/>
</options>
Option
validation.listField Field

Rejects any new values for this field that are not listed as a valid TagValuePair.

<options>
<validation.listField/>
</options>