Skip to content

fix(java): place bean-validation @Valid on the type argument instead of the container (HV000271) - #24176

Open
twonky4 wants to merge 1 commit into
OpenAPITools:masterfrom
twonky4:fix/hv000271-java
Open

fix(java): place bean-validation @Valid on the type argument instead of the container (HV000271)#24176
twonky4 wants to merge 1 commit into
OpenAPITools:masterfrom
twonky4:fix/hv000271-java

Conversation

@twonky4

@twonky4 twonky4 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Fixes Hibernate Validator HV000271 ("Using @Valid on a container is deprecated. You should apply the annotation on the type argument(s)") across the Java generator family. HV 9.1+ (bundled with Spring Boot 4) logs this at WARN for every @Valid-annotated List/Set/Map — on both model properties and API parameters.

The fix relocates @Valid from the container to its type argument — the Bean-Validation-2.0 form (List<@Valid T>, Map<String, @Valid V>) — which cascades identically but is not deprecated. Backward-compatible: element validation is preserved, never dropped.

Scope (Java family): spring, java client, JAX-RS (jersey, resteasy(+eap), cxf(+extended/cdi), spec), java-camel.

  • Models (property/getter): the container @Valid is moved to the type argument. Map values are gated behind a new AbstractJavaCodegen#useBeanValidationOnMapValueType() (default false; overridden true in Spring/JavaClient/JAX-RS) so untouched generators don't silently gain map-value validation. Arrays/sets already injected the type-argument form.
  • Parameters (@RequestBody/@RequestParam/@RequestPart): the redundant container-level @Valid is dropped for container parameters; element validation is driven by the type-argument @Valid. Single-object parameters keep their @Valid. Reactive Mono/Flux bodies are intentionally untouched — they are not Jakarta containers and do not trigger HV000271.

The microprofile client bodyParams change is a consistency change with no sample impact (those samples don't enable bean validation).

Tests: added SpringCodegenTest#beanValidationOnContainerTypeArgument_issue23614 and #beanValidationOnContainerParameter_issue23614, JavaClientCodegenTest#testBeanValidationOnContainerTypeArgument_issue23614, updated JavaJAXRSSpecServerCodegenTest; the reactive test now also asserts the parameter-level @Valid is retained.

Fixes #23614

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Stops Hibernate Validator HV000271 by moving bean-validation from containers to their type arguments without changing cascade behavior. Old: @Valid on List/Set/Map containers. New: List<@Valid T>, Map<String, @Valid V>. Single-object parameters stay @Valid; reactive Mono/Flux keep parameter-level @Valid.

  • Models: remove container-level @Valid; place it on array/set elements. Map values use type-argument validation gated by AbstractJavaCodegen#useBeanValidationOnMapValueType() (default false; overridden true in SpringCodegen, JavaClientCodegen, AbstractJavaJAXRSServerCodegen).
  • Parameters: drop container-level @Valid on @RequestBody, @RequestParam, @RequestPart for containers; keep for non-containers. Reactive bodies retain parameter-level @Valid and add type-argument validation inside Mono/Flux.
  • Updated Java, JAX-RS, Spring, and java-camel templates; added/updated tests (Spring, Java client, JAX-RS, array primitives) and regenerated samples.

Written for commit 0d1b1d1. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 579 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/openapi3/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/model/ArrayOfArrayOfNumberOnly.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/model/ArrayOfArrayOfNumberOnly.java:50">
P3: Unused `jakarta.validation.Valid` import remains after the only `@Valid` annotation in the class was removed.</violation>
</file>

<file name="samples/client/petstore/java/rest-assured/src/main/java/org/openapitools/client/model/ArrayOfNumberOnly.java">

<violation number="1" location="samples/client/petstore/java/rest-assured/src/main/java/org/openapitools/client/model/ArrayOfNumberOnly.java:64">
P3: `javax.validation.Valid` import is unused after the only @Valid annotation was removed from the getter. This leaves stale generated code that can trigger lint/checkstyle failures.</violation>
</file>

Note: This PR contains a large number of files. cubic only reviews up to 200 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.

Re-trigger cubic

@@ -47,7 +47,7 @@ public ArrayOfArrayOfNumberOnly addArrayArrayNumberItem(List<BigDecimal> arrayAr
* Get arrayArrayNumber

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: Unused jakarta.validation.Valid import remains after the only @Valid annotation in the class was removed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/openapi3/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/model/ArrayOfArrayOfNumberOnly.java, line 50:

<comment>Unused `jakarta.validation.Valid` import remains after the only `@Valid` annotation in the class was removed.</comment>

<file context>
@@ -47,7 +47,7 @@ public ArrayOfArrayOfNumberOnly addArrayArrayNumberItem(List<BigDecimal> arrayAr
    * @return arrayArrayNumber
    */
-  @Valid 
+  
   @Schema(name = "ArrayArrayNumber", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
   @JsonProperty("ArrayArrayNumber")
</file context>

*/
@javax.annotation.Nullable
@Valid

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: javax.validation.Valid import is unused after the only @Valid annotation was removed from the getter. This leaves stale generated code that can trigger lint/checkstyle failures.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/rest-assured/src/main/java/org/openapitools/client/model/ArrayOfNumberOnly.java, line 64:

<comment>`javax.validation.Valid` import is unused after the only @Valid annotation was removed from the getter. This leaves stale generated code that can trigger lint/checkstyle failures.</comment>

<file context>
@@ -61,7 +61,6 @@ public ArrayOfNumberOnly addArrayNumberItem(BigDecimal arrayNumberItem) {
    */
   @javax.annotation.Nullable
-  @Valid
 
 
   public List<BigDecimal> getArrayNumber() {
</file context>

@twonky4
twonky4 force-pushed the fix/hv000271-java branch from 4691ca2 to fd351f8 Compare July 1, 2026 18:38
@twonky4

twonky4 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

A note to save reviewers some time.

On the automated review flagging that dropping the parameter-level @Valid disables element validation

It doesn't. The generated API interface is annotated @Validated, so Spring method validation cascades into a container parameter via the type-argument @Valid (List<@Valid T> / Map<String, @Valid V>) — the parameter-level container @Valid is redundant for that and only exists to trigger the HV000271 deprecation warning.

Verified empirically on Spring Boot 3.3 (Spring 6.1 / Hibernate Validator 8) and Spring Boot 4.1 (Spring 7 / Hibernate Validator 9.1), using an isolated single-method @Validated controller (no sibling @Valid, to rule out any bean-level effect):

@RestController
@Validated
class C {
    @PostMapping("/x")
    String x(@RequestBody List<@Valid Pet> body) { return "ok"; }   // Pet.name is @NotNull
}

Posting [{}] to /x:

  • new form @RequestBody List<@Valid Pet>ConstraintViolationException: x.body[0].name: must not be null (element validation runs), no HV000271
  • old form @Valid @RequestBody List<@Valid Pet> → same ConstraintViolationException, plus HV000271 on HV 9.1+

So element validation is preserved on both Spring versions; the change only removes the deprecation warning. Single-object body parameters keep their @Valid, and reactive Mono/Flux bodies are deliberately left untouched (they are not Jakarta containers and don't trigger HV000271).

@wing328

wing328 commented Jul 22, 2026

Copy link
Copy Markdown
Member

https://github.com/OpenAPITools/openapi-generator/actions/runs/28539637986/job/84609826940?pr=24176 should be fixed in the latest master

please merge the latest into your branch and resolve the merge conflicts when you've time

@twonky4

twonky4 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

@wing328 rebased and conflicts solved.

@JFCote

JFCote commented Aug 19, 2026

Copy link
Copy Markdown
Member

@twonky4 @wing328 Do you guys need help to get this merged. I really need this in the next release and ready to help. I was coding my own fixe and was about to create a PR when I found this one.

…of the container (HV000271)

Hibernate Validator 9.1+ (bundled with Spring Boot 4) logs HV000271 ("Using
@Valid on a container is deprecated. You should apply the annotation on the
type argument(s)") for every @Valid-annotated List/Set/Map — on both model
properties and API parameters.

This relocates @Valid from the container to its type argument — the
Bean-Validation-2.0 form (List<@Valid T>, Map<String, @Valid V>) — which
cascades identically but is not deprecated. Backward-compatible: element
validation is preserved, never dropped; single-object @Valid is untouched.
Verified on Spring Boot 3.3 (Spring 6.1) and 4.1 (Spring 7): a container
parameter carrying only the type-argument @Valid still triggers element
validation via method validation, with no HV000271.

Scope (Java family): spring, java client, JAX-RS (jersey, resteasy(+eap),
cxf(+extended/cdi), spec), java-camel, java-msf4j.

Models (property/getter): the container @Valid is moved to the type argument.
Map values are gated behind a new
AbstractJavaCodegen#useBeanValidationOnMapValueType() (default false; overridden
true in Spring/JavaClient/JAX-RS) so untouched generators don't silently gain
map-value validation. Arrays/sets already injected the type-argument form.

Parameters (@RequestBody/@RequestParam/@RequestPart): the redundant
container-level @Valid is dropped for container parameters; element validation
is driven by the type-argument @Valid. Single-object parameters keep @Valid.
Reactive Mono/Flux bodies are intentionally untouched (not Jakarta containers,
so no HV000271).

Regenerated all affected samples and added/updated codegen tests in
SpringCodegenTest, JavaClientCodegenTest, JavaJAXRSSpecServerCodegenTest and
JavaValidationArrayPrimitivesTest.
@twonky4
twonky4 force-pushed the fix/hv000271-java branch from 81f2a3b to 0d1b1d1 Compare August 19, 2026 14:39
@twonky4

twonky4 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto the latest master again and resolved the conflicts (only JavaSpring/beanValidation.mustache, due to the recent @NotNull→notNull partial refactor). All GitHub Actions checks are green, including "Samples up-to-date". The only red checks are the CircleCI node1 (Perl) and node2 (cpp-restsdk) shards, which are unrelated to this Java-only change — the PR touches no Perl/C++ files, and those shards run only Perl/C++ integration tests; looks like flaky infra, a re-run should clear them. Ready for review/merge. @JFCote thanks for the offer to help!

@JFCote

JFCote commented Aug 19, 2026

Copy link
Copy Markdown
Member

@twonky4 No problem! I checked your code and it was almost exactly what I had done + other awesome additions.
Let's wait for @wing328 to merge this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG][JAVA] HV000271: Using @Valid on a container (java.util.List) is deprecated

3 participants