Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG][Spring] code generation fails if oneOf discriminator is enum #19194

Open
5 of 6 tasks
jan-mawh opened this issue Jul 18, 2024 · 4 comments
Open
5 of 6 tasks

[BUG][Spring] code generation fails if oneOf discriminator is enum #19194

jan-mawh opened this issue Jul 18, 2024 · 4 comments

Comments

@jan-mawh
Copy link

Bug Report Checklist

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

I want to limit the possible entries for the discriminator using oneOf. Therefore i want to set the discriminator as enum (See OpenAPI declaration file) below.

The openapi-generator-maven-plugin says:
[WARNING] 'cargoParent' defines discriminator 'unit', but the referenced schema 'TONS' is incorrect. invalid type for unit, set it to string
and the code finally fails to compile.

The Problem is that the generator creates the method

public TonsUnitEnum getUnit() {
    return unit;
  }

in the TONS.java class. But the CargoParents requires a method returning String:

public interface CargoParent {
    String getUnit();
}
openapi-generator version

openapi-generator-maven-plugin 7.7.0

OpenAPI declaration file content or url
openapi: 3.0.3
info:
  title: test
  contact:
    email: [email protected]
  license:
    name: company Licence
    url: https://company.de/
  version: 0.1.1
servers:
  - url: https://webservice.company.org
paths:
  /doSomething:
    post:
      summary: test
      description: description for test operation
      operationId: doSomething
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/doSomethingRequest'
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/doSomethingResponse'
components:
  schemas:
    doSomethingRequest:
      title: doSomethingRequest
      type: object
      properties:
        cargo:
          $ref: '#/components/schemas/cargoParent'
      required:
        - cargo
    doSomethingResponse:
      title: doSomethingResponse
      type: object
    TonsUnitEnum:
      type: string
      enum:
        - Tons
    TONS:
      title: TONS
      type: object
      properties:
        unit:
          $ref: '#/components/schemas/TonsUnitEnum'
        amount:
          type: number
          format: double
          example: 40
          minimum: 0
      required:
        - unit
        - amount
    KILOGRAMS:
      title: KILOGRAMS
      type: object
      properties:
        unit:
          type: string
          pattern: ^KILOGRAMS$
          example: KILOGRAMS
        amount:
          type: number
          format: double
          example: 1000
          minimum: 0
      required:
        - unit
        - amount
    cargoParent:
      title: cargoParent
      type: object
      oneOf:
        - $ref: '#/components/schemas/TONS'
        - $ref: '#/components/schemas/KILOGRAMS'
      discriminator:
        propertyName: unit
        mapping:
          TONS: '#/components/schemas/TONS'
          KILOGRAMS: '#/components/schemas/KILOGRAMS'
Related issues/PRs

#12412

@jan-mawh
Copy link
Author

bye the way: when removing the enum from TonsUnitEnum everything works fine. So with:

TonsUnitEnum:
      type: string

code compiles perfectly

@michael-adjaye-nutmeg
Copy link

michael-adjaye-nutmeg commented Sep 5, 2024

bye the way: when removing the enum from TonsUnitEnum everything works fine. So with:

TonsUnitEnum:
      type: string

code compiles perfectly

But does the data type on your concrete class become a String after removing the enum from TonsUnitEnum? This is what happens for me - which is not ideal...

@jan-mawh
Copy link
Author

jan-mawh commented Sep 6, 2024

But does the data type on your concrete class become a String after removing the enum from TonsUnitEnum? This is what happens for me - which is not ideal...

Yes it becomes a string - which is (as you already mentioned) not ideal. I would like it to be an enum. I figured out a workaround using a regex pattern (see example with KILOGRAMS) - but this is also not ideal:

    KILOGRAMS:
      title: KILOGRAMS
      type: object
      properties:
        unit:
          type: string
          pattern: ^KILOGRAMS$
          example: KILOGRAMS

Below is an even better example why i would like to use an enum. TONS and KILOGRAMS both include cargoGeneralParameter with an allOf. And cargoGeneralParameter has the unit discrimitator which should either be "TONS " or "KILOGRAMS " - that's why an enum would be much better than a string:

openapi: 3.0.3
info:
  title: test
  contact:
    email: [email protected]
  license:
    name: company Licence
    url: https://company.de/
  version: 0.1.1
servers:
  - url: https://webservice.company.org
paths:
  /doSomething:
    post:
      summary: test
      description: description for test operation
      operationId: doSomething
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/doSomethingRequest'
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/doSomethingResponse'
components:
  schemas:
    doSomethingRequest:
      title: doSomethingRequest
      type: object
      properties:
        cargo:
          $ref: '#/components/schemas/cargoInterface'
      required:
        - cargo
    doSomethingResponse:
      title: doSomethingResponse
      type: object
    cargoInterface:
      oneOf:
        - $ref: '#/components/schemas/TONS'
        - $ref: '#/components/schemas/KILOGRAMS'
      discriminator:
        propertyName: unit
    TONS:
      allOf:
        - $ref: '#/components/schemas/cargoGeneralParameter'
        - type: object
          properties:
            amount:
              type: integer
          required:
            - amount
    KILOGRAMS:
      allOf:
        - $ref: '#/components/schemas/cargoGeneralParameter'
        - type: object
          properties:
            amount:
              type: number
              format: double
              example: 1000
              minimum: 0
          required:
            - amount
    cargoGeneralParameter:
      type: object
      properties:
        unit:
          type: string
          enum:
            - KILOGRAMS
            - TONS
        cargoId:
          type: integer
      required:
        - unit
        - cargoId

@mattmcc-attest
Copy link

Hey did anyone find a fix for this without needing regex?

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

No branches or pull requests

3 participants