0
votes

In my Grails app, I am using methods in a service to do complicated validation for user submitted data. Unfortunately, Grails is quietly sabotaging me.

  1. I populate the domain instance with the user submitted data
  2. I hand the instance off to the service, which analyzes the properties.
  3. If errors are found I add them using

     instance.errors.rejectValue('myValue','errors.customErrorCode','Error') 
    
  4. BEHIND THE SCENES, when the service passes the domain instance back to the controller grails checks for changed properties and calls validate() before returning the instance. (verifiable by seeing the beforeValidate event called on returning a domain instance from a service to a controller where one or more properties has changed)

  5. That behavior clears any custom errors I have added and the instance I get back in the controller is now incorrectly without error.

How can I

A) stop grails from validating between service and controller

OR

B) prevent a validate() call from wiping my custom errors.

EDIT So far I've found one partial answer,

If you use instance.get(params.id), grails will self validate behind the scenes wiping custom errors.

If you use instance.read(params.id) you can bypass this behavior to an extent.docs

But this solution is limited by domain relationships. Any other solutions welcome.

2
I hand the instance off to the service, which analyzes the properties. If errors are found I add them... Question why are you passing it to a service to analyze properties and reject in a service ? You do all of this in the validation bean as it hits the controller.. take a look here stackoverflow.com/questions/37121551/… in the controller you call the validation bean which does the validation and you simply call if (bean.validate()) { doSoemthing.inService.(bean) } - V H
The alternative is make it throw IOException specifically if it is doing DB stuff during this bit in the service - Then finally wrap painfully around try catch in controller which then in your catch is your failure... or return the failures as a map to controller then do that same validation failure you are doing in the service in the controller and see what diff that makes. - V H

2 Answers

1
votes

Seems that it is not custom validation. It can be because of transactional service. Service opens separate transaction for each method and clears entities after method end. You can find this mentioned in docs(read the last paragraph of part ). So errors dessappear not because of validation.

Don't know if your service is transactional. But if it is - you can add @NotTransactional annotation to method were you want not to loose errors. And errors will be saved.

Hope it helped, Matvei.

0
votes

Not sure how your code looks like or what is causing the problem, but in any case I strongly suggest implementing custom validators in the domain class or in a command object within the constrains.

Here are some examples from grails docs: http://docs.grails.org/2.4.0/ref/Constraints/validator.html