Swagger-codegen: [Java] swagger-codegen-maven-plugin does not use inheritance (extends) in generated classes

Created on 3 Sep 2019  路  4Comments  路  Source: swagger-api/swagger-codegen

Description

In our swagger.yaml file, we have a definition Cat that uses allOf to include all properties of Pet.

Cat:
  allOf:
    - $ref: '#/definitions/Pet'
    - type: object
      properties:
      # ...

The expectation is that when generating Java sources, we get

public class Cat extends Pet {

This works when using the Swagger Editor.

When using swagger-codegen-maven-plugin with _no_ configOptions set, we get the following:

public class Cat {

Cat implements all of Pet's properties itself, instead of extending it.

Swagger-codegen version

swagger-codegen-maven-plugin version 2.4.8

Swagger declaration file content or url
swagger: '2.0'

info:
  version: 1.0.0
  title: simple inheritance

tags:
  - name: "pet"

paths:
  /cat:
    put:
      tags:
        - "pet"
      operationId: "updateCat"
      consumes:
        - "application/json"
      parameters:
        - in: "body"
          name: "body"
          required: true
          schema:
            $ref: "#/definitions/Cat"
      responses:
        200:
          description: Nada

definitions:
  Pet:
    type: "object"
    required:
      - "name"
    properties:
      name:
        type: "string"
        example: "doggie"
  Cat:
    allOf:
      - $ref: '#/definitions/Pet'
      - type: object
        properties:
          huntingSkill:
            type: string
        required:
          - huntingSkill
Command line used for generation

mvn clean generate-sources

Steps to reproduce

1) Create empty maven project
2) add swagger.yaml to src/main/resources/
3) add build block to pom.xml:
xml <build> <plugins> <plugin> <groupId>io.swagger</groupId> <artifactId>swagger-codegen-maven-plugin</artifactId> <version>2.4.8</version> <executions> <execution> <id>generate-swagger</id> <phase>generate-sources</phase> <goals> <goal>generate</goal> </goals> <configuration> <inputSpec>${project.basedir}/src/main/resources/swagger.yaml</inputSpec> <language>java</language> <configOptions> <sourceFolder>src/gen/java/main</sourceFolder> </configOptions> </configuration> </execution> </executions> </plugin> </plugins> </build>
4) run mvn clean generate-resources
5) Open Swagger Editor
6) Paste swagger.yaml content into editor
7) Generate code
8) Compare model

Related issues/PRs

https://github.com/swagger-api/swagger-codegen/issues/6148 seems to report that this is not working online (which it currently is for the test data provided here) but instead offline (which it isn't for the data here with the latest stable build), so this is potentially a regression.

Suggest a fix/enhancement

n/a

Most helpful comment

try with add the discriminator: type

definitions:
  Pet:
    type: "object"
   discriminator: "type"
    required:
      - "name"
    properties:
      name:
        type: "string"
        example: "doggie"

All 4 comments

try with add the discriminator: type

definitions:
  Pet:
    type: "object"
   discriminator: "type"
    required:
      - "name"
    properties:
      name:
        type: "string"
        example: "doggie"

@chiochuan Thanks, that works as a workaround. Although it's currently not necessary online, or for other languages, like TypeScript.

Also, I think the solution is a bit surprising, given what the docs for the OpenAPI Specification Version 2.0 specify for the discriminator Fixed Field:

Adds support for polymorphism. The discriminator is the schema property name that is used to differentiate between other schema that inherit this schema. The property name used MUST be defined at this schema and it MUST be in the required property list. When used, the value MUST be the name of this schema or any schema that inherits it.

And that's precisely not how it's used in the workaround: Neither is type a property, nor is it required. But maybe I'm just reading that bit al wrong...

In other words, I'm a bit confused as to why this actually does work at all... ;-)

If I don't have a discriminator property, how do I set that up? I was relying on the old generation that used extends and honestly prefer that behavior over the duplication of fields. I didn't want (nor can, to be honest) alter the model attributes just for having that.

@HugoMario With this fix I started getting "inheritance" instead of "composition" in the models generated unexpectedly(there's no discriminator attribute specified) and as a result in runtime the de-serialization fails with "missing discriminator field <>" error.
Is it as expected??
How do I make it work without discriminator now?

Was this page helpful?
0 / 5 - 0 ratings