Repository navigation
Labels
Description
I need to annoted a type argument to apply bean validation for each Collection elements ( List, Set)
// constraint violation when some element is null
@Valid
private List<@jakarta.validation.constraints.NotNull Stubb> sample= new ArrayList<>();
but a property x-field-extra-annotation only mark a property. ex.:
// constraint violation when my list is null
@Valid
@jakarta.validation.constraints.NotNull
private List<Stubb> sample = new ArrayList<>();
for solve a problem I think about create a new one ( ex.: x-inner-validation) for use like this:
sample:
type: array
items:
x-inner-validation: '@jakarta.validation.constraints.NotNull'
allOf:
- $ref: '#/components/schemas/Stubb'
I try to edit a pojo.mustache ( JavaSpring/Pojo.mustache) follow my attempt:
property:
{{#isContainer}}
{{#useBeanValidation}}@Valid{{/useBeanValidation}}
{{#openApiNullable}}
private {{>nullableAnnotation}}{{#isNullable}}{{>nullableDataTypeBeanValidation}} {{name}} = JsonNullable.<{{{items.vendorExtensions.x-inner-validation}}}{{{datatypeWithEnum}}}>undefined();{{/isNullable}}{{^required}}{{^isNullable}}{{>nullableDataTypeBeanValidation}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/isNullable}}{{/required}}{{#required}}{{^isNullable}}{{>nullableDataTypeBeanValidation}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}};{{/isNullable}}{{/required}}
{{/openApiNullable}}
{{^openApiNullable}}
private {{>nullableAnnotation}}{{#isSet}}Set{{/isSet}}{{^isSet}}List{{/isSet}}<{{{items.vendorExtensions.x-inner-validation}}} {{{items.datatypeWithEnum}}}> {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{^defaultValue}} = new {{#isSet}}LinkedHashSet{{/isSet}}{{^isSet}}ArrayList{{/isSet}}<>(){{/defaultValue}};
{{/openApiNullable}}
{{/isContainer}}
{{^isContainer}}
getter:
public {{>nullableAnnotation}}{{#isContainer}}{{#isSet}}Set{{/isSet}}{{^isSet}}List{{/isSet}}<{{{items.vendorExtensions.x-inner-validation}}} {{{items.datatypeWithEnum}}}>{{/isContainer}}{{^isContainer}}{{>nullableDataTypeBeanValidation}}{{/isContainer}} {{getter}}() {
return {{name}};
setter
{{#jackson}}{{^vendorExtensions.x-is-jackson-optional-nullable}}{{>jackson_annotations}}{{/vendorExtensions.x-is-jackson-optional-nullable}}{{/jackson}}
public void {{setter}}({{>nullableAnnotation}}{{#isContainer}}{{#isSet}}Set{{/isSet}}{{^isSet}}List{{/isSet}}<{{{items.vendorExtensions.x-inner-validation}}} {{{items.datatypeWithEnum}}}>{{/isContainer}}{{^isContainer}}{{>nullableDataType}}{{/isContainer}} {{name}}) {
this.{{name}} = {{name}};
this config is breaking when I try to use a Set instead of List, but I paste here to try to help a develop a new config. Thank you
Reacted by Jefferson Ramos
Activity
feat(spring): add x-inner-validation vendor extension for collection …
juniorjrjl commentedon May 12, 2026
Nice ! I think this issue could be usefull for another projects too. Any other projects how use Bean Validation. ex.: Kotlin and Spring, I don't know if have another options how use use Bean validation in another plugins.
Sorry for say this just now, because I start tu use recently this project in my work and I don't know another modules
lcf2014 commentedon Jul 24, 2026
Following issue
jpfinne commentedon Sep 29, 2026
@juniorjrjl I have another option. See #25049
I think the main goal is to generate
@NotNulllike inList<@NotNull String>.It can be done for all Lists with
additionalItemsAnnotations=@NotNull. (there is already a import on jakarta.validation.constraints.* if BeanValidation is enabled)For a specific list, use the standard
x-field-extra-annotation: @NotNullinside the items.juniorjrjl commentedon Sep 29, 2026
@jpfinne nice and thank you
jpfinne commentedon Sep 29, 2026
@adraarda23 what do you think?
adraarda23 commentedon Oct 1, 2026
@jpfinne
Your approach is better than mine. Having it in
AbstractJavaCodegencovers every Java generator, and reusing the existingx-field-extra-annotationis the easier path: a new extension would be one more thing to document, learn and maintain. Happy for #25049 to land; I'll close #23710.One thing I ran into while testing your branch.
The item annotation is silently dropped when
itemsis a plain$refTake a request with two lists, where only one of them should reject
nullelements:OAS 3.0 ignores siblings of
$ref, so the annotation never reaches the generator:No annotation, no warning — the line is simply ignored.
additionalItemsAnnotations=@NotNulldoes produce it, but it is a generator-wideflag, so it also lands on the list that should accept nulls:
So there is no way to annotate one list: either every list gets it, or that schema
has to be rewritten with the
allOfwrapper from yourlistCodetest.Is
allOfthe intended way here, or would it make sense to also read the extension from the array property level?One heads-up on that
allOfroute: it currently loses@Valid, soOrderLine's own constraints stop being validated. That's pre-existing —getBeanValidation()never looks atallOf, soitems: allOf: [$ref]drops@Validwith or without your change. Not your PR's problem, but worth knowing since your PR makesallOfthe route for$refitems. I'll file it separately and link it here.jpfinne commentedon Oct 2, 2026
@adraarda23 thanks for your review
Indeed there is a limitation in the swagger parser, even for 3.1. See discussion in swagger-api/swagger-parser#798
You need to add the annotation AND to convert to allOf. Two manual steps...
I'll document it.
Maybe the OpenApiNormalizer could use x-inner-validation and convert the $ref to an AllOf ?
jpfinne commentedon Oct 2, 2026
@adraarda23 sample of a normalizer to move extensions from array to items.extensions.
#25105
What do you think?