OpenAPITools / OpenAPITools/openapi-generator

[BUG][Kotlin][kotlin-spring] Multi-level inheritance doesn't work

Open
#18,206 9 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

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

When using multi-level inheritance, the kotlin-spring generator produces non-compiling code.

> Task :compileKotlin FAILED
e: .../src/main/kotlin/org/openapitools/model/BigDog.kt: (21, 1): Function 'component1' generated for the data class conflicts with member of supertype 'Dog'
e: .../src/main/kotlin/org/openapitools/model/BigDog.kt: (21, 1): Function 'component2' generated for the data class conflicts with member of supertype 'Dog'
e: .../src/main/kotlin/org/openapitools/model/BigDog.kt: (21, 1): Function 'component3' generated for the data class conflicts with member of supertype 'Dog'
e: .../src/main/kotlin/org/openapitools/model/BigDog.kt: (31, 32): 'breed' in 'Dog' is final and cannot be overridden
e: .../src/main/kotlin/org/openapitools/model/BigDog.kt: (32, 5): This type is final, so it cannot be inherited from
e: .../src/main/kotlin/org/openapitools/model/BigDog.kt: (32, 5): This type has a constructor, and thus must be initialized here

It's especially unfortunate because Java does support this. We must use mechanisms that work across Java & Kotlin and therefore we have to go with the least common denominator preventing us from using multi-level polymorphism.

openapi-generator version
% openapi-generator --version
openapi-generator-cli 7.0.1
  commit : 5b720de
  built  : -999999999-01-01T00:00:00+18:00
  source : https://github.com/openapitools/openapi-generator
  docs   : https://openapi-generator.tech/
OpenAPI declaration file content or url
openapi: 3.0.0
info:
  title: Sample API
  description: API description in Markdown.
  version: 1.0.0
paths:
  /animals:
    get:
      summary: Returns all animals.
      description: Optional extended description in Markdown.
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Animal'
components:
  schemas:
    Dog:
      allOf:
        - $ref: '#/components/schemas/Animal'
        - type: object
          properties:
            breed:
              type: string
    Cat:
      allOf:
        - $ref: '#/components/schemas/Animal'
        - type: object
          properties:
            breed:
              type: string
    BigDog:
      allOf:
        - $ref: '#/components/schemas/Dog'
        - type: object
          required:
            - dogType
          properties:
            dogType:
              type: string
            declawed:
              type: boolean
    Animal:
      type: object
      discriminator:
        propertyName: className
      required:
        - className
      properties:
        className:
          type: string
        color:
          type: string
          default: red
Generation Details
openapi-generator generate -g kotlin-spring -i spec.yaml --additional-properties documentationProvider=none --additional-properties useSpringBoot3=true
Steps to reproduce
  1. run generation command above
  2. run gradle build
Related issues/PRs

Similar issue has been submitted for Java a long time ago: https://github.com/OpenAPITools/openapi-generator/issues/3058.

Suggest a fix

Unfortunately Kotlin doesn't support data class inheritance.

So the options I can think of:

  • generate an interface hierarchy and use data classes for the "leaf" DTOs: e.g. interfaces: IAnimal, IDog : IAnimal, data classes: Cat : IAnimal, Dog: IDog, BigDog: IDog not very pretty but most times you work with the DTOs.
  • move away from data classes - use regular classes, however this would prevent usage of data class capabilities (e.g. copy) which I personally find very useful

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided spec.yaml and run the openapi-generator generate -g kotlin-spring command using the listed options. Then run the generated project's gradle build and inspect the BigDog, Dog, and Animal model output alongside the Kotlin compilation errors. Done means the generated multi-level inheritance example compiles without the reported conflicts.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin, openapi, spring
Domain
api, backend, tooling
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.