Skip to content

[BUG][Java][Spring] Bean Validation not emitted on additionalProperties (Map) value types #25644

Closed

Description

@vanta

Bug Report Checklist

  • Have you provided a spec/code snippet to reproduce the issue?
  • Have you tested with the latest master?
  • Have you searched for related issues/PRs?

Description

For the Java / Spring generator with useBeanValidation enabled, Bean Validation constraints declared on a map value schema (additionalProperties) are not emitted onto the generated Map field. The same constraints are correctly emitted for scalar properties and for array items, so this is specific to additionalProperties (map value) handling.

Concretely, minimum/maximum (and minLength/maxLength/pattern) placed on an additionalProperties schema produce a Map<String, Integer> / Map<String, String> field with no @Min/@Max/@Size/@Pattern — only @Valid at most. Generated clients and server-side @Valid @RequestBody therefore do not enforce the documented per-value constraint, so a request that violates the spec passes validation (and typically fails deeper in the service instead of returning 400).

Container-element validation of this kind is supported for arrays (items), which makes the map case look like an oversight rather than an intentional limitation.

openapi-generator version

Reproduced with 7.14.0; release notes for 7.15.0–7.27.0 show no fix for map-value bean validation. Related open work in this area: PR #25589 ("Keep the generic arguments of additionalProperties value types" — explicitly notes "no validation annotation is added" for map values) and issue #25592 (kotlin-spring, collection element types).

OpenAPI declaration snippet (minimal repro)

openapi: 3.0.3
info: { title: repro, version: 1.0.0 }
paths:
  /things:
    post:
      operationId: createThing
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/Thing' }
      responses:
        '201': { description: created }
components:
  schemas:
    Thing:
      type: object
      properties:
        # scalar — constraints ARE generated:
        count:
          type: integer
          minimum: 1
          maximum: 20
        # array items — constraints ARE generated:
        ids:
          type: array
          items:
            type: string
            pattern: '^[a-fA-F0-9]{24}$'
        # map (additionalProperties) value — constraints are NOT generated:
        roleToCount:
          type: object
          additionalProperties:
            type: integer
            minimum: 1
            maximum: 20

Generator used

spring (also applies to java); useBeanValidation=true.

Steps to reproduce

Generate the Spring/Java model for Thing.

Expected

The map value carries its constraints, e.g.:

private @Valid Map<String, @Min(1) @Max(20) Integer> roleToCount;

(mirroring how ids yields List<@Pattern(regexp = "^[a-fA-F0-9]{24}$") String> and count yields @Min(1) @Max(20) Integer count).

Actual

@Valid
private Map<String, Integer> roleToCount;   // no @Min/@Max on the value type

while, in the same model, the array items and the scalar property are both annotated:

private Set<@Pattern(regexp = "^[a-fA-F0-9]{24}$") String> ids;
@Min(1) @Max(20) private Integer count;

Impact

A documented per-value constraint on a map is silently dropped from the generated code, so generated clients and server @Valid do not enforce it; the contract and the runtime behaviour diverge. The only workarounds today are re-validating the mapped object in hand-written code or a vendor-extension escape hatch.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions