OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.95k stars 6.59k forks source link

[BUG] [JAVA] Generated @JsonTypeName conflicts with value of x-discriminator-value when ModelNameSuffix is used #17343

Open jpfinne opened 11 months ago

jpfinne commented 11 months ago

Bug Report Checklist

[BUG] [JAVA] Generated @JsonTypeName doesn't use the value of x-discriminator-value. Jackson created incorrect json

Description

x-discriminator-value is the only way to customize the value of the discriminator in swagger 2. Since 7.1.0 it is not taken into account anymore when modelNameSuffix is used. The name of the element is always used. It gives a huge regression in the json processing.

The parent contains the correct mapping:

@JsonSubTypes({
  @JsonSubTypes.Type(value = CatItemDto.class, name = "CAT"),
  @JsonSubTypes.Type(value = DogItemDto.class, name = "DOG")
})

But it is superseeded in the child classes

@JsonTypeName("DogItem")
public class DogItemDto extends PetItemDto {

Expected:

no @JsonTypeName annotation if you remove @JsonTypeName from template everything works fine (Jackson seems to retrieve typeName from parent).

public class DogItemDTO extends PetItemDTO {

alternatively @JsonTypeName("DOG") is also valid

@JsonTypeName("DOG") 
public class DogItemDTO extends PetItemDTO {

So that Jackson creates this json {"type":"DOG","identifier":"Medor","packSize":10}

Actual in 7.1.0 and 7.2.0

@JsonTypeName("DogItem") public class DogItemApiDTO extends PetItemApiDTO {

Jackson generates {"type":"DogItem","identifier":"Medor","packSize":10}

This json can not be unmarshalled by application using a different version of the generator. In my case typescript-angular fails to unmarshall

openapi-generator version 7.1.0

regression since 6.4.0. Maybe fix for #14731

OpenAPI declaration file content or url
swagger: "2.0"
info:
  version: 1.0.0
  title: x-discriminator-value bug
paths:
  /getItems:
    get:
      description: test
      operationId: getAllPets
      responses:
        200:
          description: 'list of PetItems'
          schema:
            type: array
            items:
              $ref: '#/definitions/PetItem'
definitions:
  PetType:
    type: string
    enum:
      - DOG
      - CAT
  PetItem:
    discriminator: type
    properties:
      identifier:
        type: string
      type:
        $ref: '#/definitions/PetType'

  DogItem:
    x-discriminator-value: DOG
    allOf:
      - $ref: '#/definitions/PetItem'
      - type: object
        properties:
          packSize:
            type: integer
  CatItem:
    x-discriminator-value: CAT
    allOf:
      - $ref: '#/definitions/PetItem'
      - type: object
        properties:
          huntingSkill:
            type: string
Generation Details

openapi-generator-cli generate -i swaggerDiscriminator.yaml -g spring --model-name-suffix=Dto

Steps to reproduce

Contract in swagger-2 inheritance with a discriminator use of x-discriminator-value modelNameSuffix

Use the spring generator.

Related issues/PRs

10822

Suggest a fix

Update pojo.mustache to use the vendorExtensions.x-discriminator-value if it exists

{{^hasDiscriminatorWithNonEmptyMapping}} @JsonTypeName("{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{vendorExtensions.x-discriminator-value}}{{/vendorExtensions.x-discriminator-value}}") {{/hasDiscriminatorWithNonEmptyMapping}}

jroch commented 11 months ago

Same issue here.

dragutint commented 3 months ago

Same issue here, 7.7.0 version. jaxrs-spec server generator, with and without ModelNameSuffix. With java generator and native library it generates a class without @JsonTypeName annotation and with @JsonIgnoreProperties annotations, and (de)serialization works fine this way.

If possible, I would like to contribute to fixing this issue.

pboos commented 2 months ago

Is there a workaround for this?

@jpfinne I saw your very promising PR: https://github.com/OpenAPITools/openapi-generator/pull/17781 What is the reason that it got closed? Would have been great to get that one in as it would have solved this issue.

vicinzu commented 1 month ago

Same issue here. Version: 7.9.0

My temporary workaround is to add a mix-in to the object mapper with the correct annotation, e.g.

configure min-ins

objectMapper.addMixIn(CatItemDto.class, CatItemDtoMinIn.class);
objectMapper.addMixIn(DogItemDto.class, DogItemDtoMinIn.class);

CatItemDtoMinIn

@JsonTypeName("CAT")
public abstract class CatItemDtoMinIn {

}

DogItemDtoMinIn

@JsonTypeName("DOG")
public abstract class DogItemDtoMinIn {

}