Skip to content

fix(kotlin-spring): skip @field:Valid on Map container properties (HV000271) - #24029

Closed
fabb wants to merge 1 commit into
OpenAPITools:masterfrom
fabb:fix/valid-container-warning
Closed

fabb wants to merge 1 commit into
OpenAPITools:masterfrom
fabb:fix/valid-container-warning

Conversation

@fabb

@fabb fabb commented Jun 15, 2026 •

Copy link
Copy Markdown

Description

Hibernate Validator 9.1 deprecated placing @Valid directly on a Map container, emitting a HV000271 warning at startup:

Using @Valid on a container (java.util.Map) is deprecated. You should apply the annotation on the type argument(s).

The beanValidation.mustache template adds @field:Valid to all container properties (List, Map, …) whose items are not primitives. For Map properties the correct fix is to omit @field:Valid entirely — annotating a type argument of Map<K, Any> or Map<K, SomeModel> with @Valid would require type-use annotations, which the current codegen does not support, and for untyped maps (Any values) there is nothing to validate anyway.

Change

Add a {{^isMap}} guard to the container branch of beanValidation.mustache so that only List/Set/array-typed properties still get @field:Valid. Map-typed properties are left unannotated.

Testing

  • Added a new @Test in KotlinSpringServerCodegenTest: generates a model with one Map<String, Item> property and one List<Item> property, then asserts that exactly one @field:Valid annotation is present in the generated file (for the list only).
  • All existing kotlin-spring sample outputs regenerated — no diff (none of the petstore samples have Map<String, ComplexType> properties).

Summary by cubic

Skip emitting @field:Valid on Map properties in Kotlin Spring codegen to prevent HV000271 warnings with Hibernate Validator 9.1. Lists/Sets/arrays are unchanged.

  • Bug Fixes
    • Updated kotlin-spring/beanValidation.mustache to apply @field:Valid only when isContainer && !isMap.
    • Added a test to ensure only the list property gets @field:Valid; regenerated samples with no changes.

Written for commit b959b17. Summary will update on new commits.

Review in cubic

…000271)

Hibernate Validator deprecated placing @Valid on a Map container
(HV000271) — the annotation must instead be on the type argument.
Since the Map value type is often untyped (Any/Object), the correct
fix is to omit @field:Valid from Map properties entirely.

Add {{^isMap}} guard to the container branch of beanValidation.mustache
so that only List/Set/Array containers still get @field:Valid.

@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.

No issues found across 3 files

Re-trigger cubic

@fabb

fabb commented Jun 15, 2026 •

Copy link
Copy Markdown
Author

Trade-off: validation of map values

For a property like Map<String, SomeModel>, @Valid on the map tells Hibernate Validator to cascade into each value and check SomeModel's own constraints. HV 9.1 deprecated @Valid on the map itself (HV000271) and wants the annotation on the value type instead — Map<String, @Valid SomeModel>. That form is a type-use annotation, which the kotlin-spring generator can't emit yet.

So the options are: keep @Valid (cascade works, but every app logs the deprecation warning) or drop it (no warning, but map values are no longer validated). This PR drops it.

Consequence: constraints declared inside SomeModel aren't checked when it appears as a map value. Constraints on the map property itself (@NotNull, @Size) are unaffected, and List/Set/array properties keep @field:Valid. The common Map<String, Any> case has nothing to cascade into, so loses nothing.

The fuller fix — emitting Map<K, @Valid V> to preserve cascading without the deprecation — needs type-use annotation support and is out of scope here. The JavaJaxRS/spec generator already solves this by reconstructing the type in the template and injecting the annotation at the element position; see beanValidatedType.mustache, introduced in #11709 (issue #11707). That's the reference for a follow-up that ports the same approach to kotlin-spring.

@fabb

fabb commented Jun 15, 2026 •

Copy link
Copy Markdown
Author

Closing this since it does not properly fix the underlying issue.

Dropping @field:Valid from Map properties silences HV000271, but the deprecated form still works in Hibernate Validator 9.1 — @Valid on a Map cascades into the values, retained for Bean Validation 1.1 backward compatibility, and the warning is currently harmless. So for Map<String, SomeModel> this change would remove validation that still functions today, trading working behaviour for a silenced warning. That's the wrong trade.

The right fix is to emit the type-use form Map<K, @Valid V> (and List<@Valid T>), which silences the deprecation and preserves cascading. The JavaJaxRS/spec generator already does this by reconstructing the type in the template and injecting the annotation at the element position — see beanValidatedType.mustache, introduced in #11709 (issue #11707). kotlin-spring should adopt the same approach.

Closing rather than causing more issues.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant