Reference‎ > ‎

Rules: Constraint

Definition

A Constraint is defined by a method with the @Constraint annotation:

import com.autobizlogic.abl.businesslogic.annotations.*;
import com.autobizlogic.abl.businesslogicengine.ConstraintFailure;

public class CustomerLogic {

    @CurrentBean
    private Customer customer;
    
    @Constraint
    public void myConstraint() {
        if (customer.getBalance() > 1000)
           ConstraintFailure.failConstraint("Customer " + customer.getName() + 
                " needs to spend less.");
    }

The name of the method has no special meaning.

Parameters

 <value> [optional] an expression that should evaluate to true or false. If it evaluates to false, the Constraint will fail.
 problemAttributes [optional] the name(s) of one or more attributes that are related to the failure of this Constraint. This may allow a GUI to highlight the relevant portions. More than one attribute can be specified as a comma-separated list.
 errorMessage [optional] the error message that should be included in the exception that is thrown when the Constraint fails. This is only taken into account if an expression is specified in the annotation.
The message can reference attribute of the bean using the {attributeName} convention.
 verbs [optional] the verb(s) under which this constraint should execute. Can specify any combination of INSERT, UPDATE or DELETE. If specified, the constraint will only execute in those conditions. If not specified, the constraint will always execute.

Declarative constraint

If the annotation contains a value (a boolean expression), it is known as a declarative constraint.

For example:

@Constraint("balance <= creditLimit")
public void myConstraint() { }

A more complete example:

@Constraint(
        value = "balance <= creditLimit",
        problemAttributes = "balance, creditLimit",
              verbs = Verbs.ALL,
        errorMessage = "Customer {name} has exceeded credit limit {creditLimit}"
)
public void myConstraint() { }

Declarative constraints can also contain code, and that code will be invoked, but any exception thrown in that code will be caught and ignored. The purpose of invoking the code in this case is mostly for debugging.

Expression language

The expression (if provided) is currently interpreted using Apache JEXL. You do therefore have complete access to its powerful language.

However, it is generally recommended to keep the expression simple. Anything more complex should be handled in code, which is much easier to debug.

In addition, it should be noted that the expression is interpreted, and is therefore much slower than code. If performance is critical, code should be used.

Effect

A Constraint is invoked any time an object is inserted, updated or deleted. It is meant to verify that a certain condition is true.

If that condition is not true, the code must invoke ConstraintFailure.failConstraint, which will throw an exception. The current transaction will be rolled back, but execution of the rules does not stop. It is therefore possible to have more than one Constraint fail during one transaction.

A Constraint may be invoked more than once during a transaction, if the rules execution requires it.

A Constraint should not have any persistent side-effects: it should not modify the object (or any other persistent object). An Action should be used for that purpose.

Comments