Skip to content

[BUG][JAVA] OpenAPI 3.1.0 type array ["object", "null"] with $ref incorrectly treated as map #22919

@GeorgSawtschuk

Description

@GeorgSawtschuk

Bug Report Checklist

  • [X ] Have you provided a full/minimal spec to reproduce the issue?
  • [ X] Have you validated the input using an OpenAPI validator?
  • [ X] Have you tested with the latest master to confirm the issue still exists?
  • [X ] Have you searched for related issues/PRs?
  • [ X] What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When using OpenAPI 3.1.0 type arrays (e.g. type: ["object", "null"]) as a replacement for the deprecated nullable from OpenAPI 3.0.0, the openapi-generator incorrectly treats the attribute as a map instead of a typed object reference. This results in a broken putXxxItem method being generated with a missing type parameter.

For example, the attribute Kunde.zahlungsverbindung is declared as type: ["object", "null"] with a $ref to Zahlungsverbindung. The generator produces a broken method:

  public Kunde putZahlungsverbindungItem(String key,  zahlungsverbindungItem) {
    if (this.zahlungsverbindung == null) {
      this.zahlungsverbindung = new HashMap<>();
    }
    this.zahlungsverbindung.put(key, zahlungsverbindungItem);
    return this;
  }

The problems are:

  1. zahlungsverbindung is not a map, it is a nullable object reference.
  2. The type is missing because {{items}} is not resolved in the mustache template.

The OpenAPI 3.1.0 migration guide recommends using type arrays instead of nullable: https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0 ("Swap nullable for type arrays").

openapi-generator version

7.19.0 (also tested with latest version; not a regression, issue persists across versions)

OpenAPI declaration file content or url

Reproducer project: https://github.com/GeorgSawtschuk/TypeArrayNullable

openapi: 3.1.0
info:
  title: Reproducer - type array nullable bug
  version: 1.0.0

paths:
  /kunde:
    get:
      operationId: getKunde
      summary: Liefert einen Kunden zurück
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Kunde'

components:
  schemas:
    Kunde:
      type: object
      properties:
        zahlungsverbindung:
          type:
            - "object"
            - "null"
          $ref: '#/components/schemas/Zahlungsverbindung'

    Zahlungsverbindung:
      type: object
      properties:
        iban:
          type: string
        bic:
          type: string
Generation Details

Generator: java
Library: webclient
CLI equivalent:

openapi-generator-cli generate \
  -i src/main/resources/openapi.yaml \
  -g java \
  --library webclient \
  --additional-properties=useJakartaEe=true,sourceFolder=src/gen/java,modelPackage=gsaw.model,openApiNullable=false \
  --generate-api-tests=false \
  --generate-model-tests=false

Maven plugin configuration used:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>7.19.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>src/main/resources/openapi.yaml</inputSpec>
                <generatorName>java</generatorName>
                <library>webclient</library>
                <generateApis>false</generateApis>
                <generateApiTests>false</generateApiTests>
                <generateModelTests>false</generateModelTests>
                <generateSupportingFiles>false</generateSupportingFiles>
                <configOptions>
                    <useJakrartaEe>true</useJakrartaEe>
                    <sourceFolder>src/gen/java</sourceFolder>
                    <modelPackage>gsaw.model</modelPackage>
                    <openApiNullable>false</openApiNullable>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>
Steps to reproduce
  1. Clone the reproducer project: https://github.com/GeorgSawtschuk/TypeArrayNullable
  2. Try to build the project with mvn compile.
  3. Observe the generated model class for Kunde.
  4. The zahlungsverbindung property is incorrectly treated as a map, generating a broken putZahlungsverbindungItem method with a missing type parameter.
Related issues/PRs

This is related to OpenAPI 3.1.0 type array support (nullable via type: ["object", "null"]).

Suggest a fix

A workaround exists: modify pojo.mustache to add an {{#items}} constraint in addition to {{#isMap}}, so the putXxxItem method is only generated when items can actually be resolved. See the modified template in openapi/pojo.mustache (lines 173-199) in the reproducer project. To enable the workaround, uncomment the templateDirectory line in pom.xml.

The root cause appears to be that the generator incorrectly classifies properties with type: ["object", "null"] as maps. The fix should ensure that type arrays containing "object" and "null" are recognized as nullable object references, not as map types.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions