Grails: manually rejected field values are not displayed

Let’s say you want to reject a value manually for a domain class using Spring Errors interface. You call reject or rejectValue methods, but errors are not displayed on UI. So there are some things you have to check:

  • You will miss all errors for manually rejected values after the call of validate() or save(), because these methods clean validation errors and recreates them based on constraints
  • Check if message code for error exists in i18n file. If the code doesn’t exist and no default value is provided, message will not be displayed
  • Change code in update method that checks if instance can be saved to discard changes. Errors for manually rejected values will not prevent instance from being saved, so instance.hasErrors() will return false and errors object will not contain any errors: 

      if (!instance.hasErrors() && instance.save(flush: true)) {
         ...
      } else {
          //reload all lazy fields to prevent lazy loading error
          instance.collection.findAll {it}
          //discard changes to show validation errors
          instance.discard()
          render(view: "edit", model: [instance: instance])
      }