Entity Editor Validation

Hey,
I have a task entity which is linked to a milestone as its composition. Tasks have weights that should not exceed 100. is there a way on the task editor to get list of added tasks so that i can do validation on the weight field so that it cannot surpass 100?
Also Is there a way i can revert a change on the addCollectionChangeListener, related to the problem above, i was trying to revert a task added when the weights surpass 100.

Hi,

Validation in the Milestone editor can be easily implemented with a custom Bean Validation constraint.

  1. Create an annotation, for example:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = TasksWeightValidator.class)
public @interface CheckTasksWeight {

    String message() default "Tasks weights surpass 100";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}
  1. Create a validator class, for example:
public class TasksWeightValidator implements ConstraintValidator<CheckTasksWeight, Milestone> {

    @Override
    public void initialize(CheckTasksWeight constraintAnnotation) {

    }
    
    @Override
    public boolean isValid(Milestone value, ConstraintValidatorContext context) {
        List<Task> tasks = value.getTasks();
        if (tasks != null) {
            int sum = 0;
            for (Task task : tasks) {
                sum += task.getWeight();
            }
            return sum <= 100;
        }
        return true;
    }
}
  1. Use the annotation in your Milestone entity class:
@CheckTasksWeight(groups = UiCrossFieldChecks.class)
@NamePattern("%s|name")
@Table(name = "ENEDVAL_MILESTONE")
@Entity(name = "enedval$Milestone")
public class Milestone extends StandardEntity {
    private static final long serialVersionUID = -5368923155145135689L;

    @Column(name = "NAME")
    protected String name;

    @Valid
    @Composition
    @OnDelete(DeletePolicy.CASCADE)
    @OneToMany(mappedBy = "milestone")
    protected List<Task> tasks;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setTasks(List<Task> tasks) {
        this.tasks = tasks;
    }

    public List<Task> getTasks() {
        return tasks;
    }
    
}

You can try the small project attached to see how it works:
enedval.zip (84.7 KB)

Another option is to prevent saving a Task if its weight + all weights in the same Milestone exceed 100. This can be done in the TaskEdit controller, and no need to implement Bean Validation in this case:

public class TaskEdit extends AbstractEditor<Task> {

    @Inject
    private Datasource<Task> taskDs;

    @Override
    protected boolean preCommit() {
        Milestone milestone = getItem().getMilestone();
        List<Task> tasks = milestone.getTasks();
        int sum = 0;

        if (tasks != null) {
            for (Task task : tasks) {
                sum += task.getWeight();
            }
        }

        sum += taskDs.getItem().getWeight();

        if (sum > 100)
            showNotification("The sum of task weights exceeds 100", NotificationType.WARNING);

        return sum <= 100;
    }
}

Hi,
The pre-commit option worked for me, I returned false if the milestone didnt add up. Thanks for the answer.