I did something similar in the planning system to prevent overlapping shifts for the same person. In the model, it uses the @PrePersist method to query the database and throws a custom exception if it detects anything that could conflict.
Then in the controller I will catch an exception (which will be thrown when the object is saved) and redirected back to the form.
In the model:
@PrePersist public void prepareToInsert() { List<AgentShift> conflicts = find("agent=?1 and (start_time between ?2 and ?3 or end_time between ?2 and ?3)", agent, sql_datetime_formatter.print(scheduled.getStart()), sql_datetime_formatter.print(scheduled.getEnd())).fetch(); if (!conflicts.isEmpty()) { throw new SchedulingException("New shift for " + agent + " overlaps existing shift which goes from " + sql_datetime_formatter.print(conflicts.get(0).scheduled.getStart()) + " to " + sql_datetime_formatter.print(conflicts.get(0).scheduled.getEnd()), conflicts); } }
In the controller:
public static void create(@Valid AgentShift object) { ... try { object._save(); ... } catch (SchedulingException e) { flash.error("conflict with existing shift", e.getConflicts()); redirect(request.controller + ".blank", object._key()); } }
source share