jdaugherty commented on PR #16624:
URL: https://github.com/apache/grails-core/pull/16624#issuecomment-6481662509

   Thanks for the second pass. The cascade edge case and the two smaller points 
are addressed in 051efbe12c ([diff against 
d3f8ba5600](https://github.com/apache/grails-core/compare/d3f8ba5600..051efbe12c)).
   
   ### 1. A class-level constraint on an associated domain class
   
   The fix is in `GormValidatorAdapter`, not in 
`JakartaPersistentEntityValidator.validateBeyondConstraints`:
   
   - The field is built inside 
`SpringValidatorAdapter.processConstraintViolations`.
   - The hooks that build the code and the arguments (`determineField`, 
`determineErrorCode`, `getArgumentsForConstraint`) are protected, so only a 
subclass of the adapter can report the violation differently.
   
   The adapter now overrides `processConstraintViolations`, and the override 
acts only when the errors have a nested path:
   
   - A violation with an empty field is reported with `rejectValue('', …)`, so 
it lands on `ranges[0]`. Its arguments are built for that path.
   - Property violations still go through Spring unchanged.
   - Without a nested path nothing changes, so a class-level violation of the 
validated object is still a global error.
   
   Regressions:
   
   - **TCK `BeanValidationSpec`** (run locally on Hibernate 5, Hibernate 7, 
MongoDB and Neo4j): `BeanValidatedPair` is now owned by a plain 
`BeanValidatedPairing`. A pair violating its class-level `@DistinctLabels` 
makes the pairing report exactly one field error, on `pairs[0]`.
   - **`GormValidatorAdapterSpec`**: validates a `PriceRange` under the nested 
path `range`. It compares the error with the one Spring reports when it 
cascades from the holder through `@Valid`, with the same field, codes, 
arguments and message. It also pins the global error of the validated object.
   
   Both fail without the adapter change.
   
   ### 2. Smaller points
   
   - **Upgrade note:**
     - Flush-time enforcement of `nullable`, `unique` and `maxSize` is now 
stated for a schema that GORM for Hibernate generated from the mapping.
     - With GORM for MongoDB and GORM for Neo4j, `nullable` and `maxSize` are 
enforced for the first time. This includes the `nullable: false` that 
`grails.gorm.default.nullable = false` gives every property without a 
nullability rule of its own.
   - **Message codes:** the guide now says that the codes of an annotation 
error found through an association name the validated class and the path, while 
the codes of the block keep the class of the associated instance. So 
`NotBlank.com.example.InvoiceLine.label` applies only to a line validated on 
its own, while `NotBlank.lines.label`, `NotBlank.label` and `NotBlank` apply 
both ways. It also says that a class-level constraint of the associated class 
is reported on the association path itself.
   - **`no ci` label:** removed, so this head gets a full CI run.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to