Java 为什么鉴别器属性被序列化两次?

Java 为什么鉴别器属性被序列化两次?,java,jackson,swagger,swagger-codegen,openapi-generator,Java,Jackson,Swagger,Swagger Codegen,Openapi Generator,我在组件模式中使用OpenAPI3.0继承,我有OpenAPI生成器(使用Jackson)生成的(Java)类 为什么鉴别器属性在结果JSON中序列化两次 这是JHipster API的第一个项目,应该使用openapi生成器生成Java模型(带有Jackson注释的POJO)和API控制器(带有Spring的@API注释的接口) 通过遵循OpenAPI 3.x文档/示例,似乎还必须在模式的properties列表中指定用作鉴别器的属性 通过这种方式,生成的Java类似乎不同于Jackson关于

我在组件模式中使用OpenAPI3.0继承,我有OpenAPI生成器(使用Jackson)生成的(Java)类

为什么鉴别器属性在结果JSON中序列化两次

这是JHipster API的第一个项目,应该使用openapi生成器生成Java模型(带有Jackson注释的POJO)和API控制器(带有Spring的@API注释的接口)

通过遵循OpenAPI 3.x文档/示例,似乎还必须在模式的
properties
列表中指定用作
鉴别器的属性

通过这种方式,生成的Java类似乎不同于Jackson关于使用annotations()处理多态类型的指导原则,其中用作鉴别器的属性不能出现在类中。相反,生成的代码还将此属性作为类属性包含在getter/setter中。这会导致JSON输出包含属性两次,如下所示

我还尝试从OpenAPI
properties
列表中删除属性,保留
鉴别器部分的完整性;通过这种方式,生成的代码符合Jackson的准则,序列化工作正常。另一方面,我在反序列化过程中遇到一个错误,因为在目标类中找不到(removed)属性

遵循OpenAPI 3.x文档指南:

TicketEvent:
  type: object
  description: A generic event
  discriminator:
    propertyName: type
  required:
    - id
    - sequenceNumber
    - timestamp
    - type
  properties:
    id:
      type: integer
      format: int64
      readOnly: true
    sequenceNumber:
      type: integer
      readOnly: true
    timestamp:
      type: string
      format: date-time
      readOnly: true
    type:
      type: string
      readOnly: true
TicketMovedEvent:
  description: A ticket move event
  allOf:
    - $ref: '#/components/schemas/Event'
    - type: object
      required:
        - source
        - target
      properties:
        source:
          $ref: '#/components/schemas/Queue'
        target:
          $ref: '#/components/schemas/Queue'
生成的类:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”,visible=true)
@JsonSubTypes({
@JsonSubTypes.Type(value=TicketMovedEvent.class,name=“TicketMovedEvent”)
})
公共类票务{
...
@JsonProperty(“类型”)
私有字符串类型;
JSON包含两次属性

{
        ...
    "type": "TicketMovedEvent",
    "type": null,
        ...
}
属性
列表中删除鉴别器属性:

TicketEvent:
  type: object
  description: A generic event
  discriminator:
    propertyName: type
  required:
    - id
    - sequenceNumber
    - timestamp
  properties:
    id:
      type: integer
      format: int64
      readOnly: true
    sequenceNumber:
      type: integer
      readOnly: true
    timestamp:
      type: string
      format: date-time
      readOnly: true
生成的类没有
类型
属性:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.PROPERTY,PROPERTY=“type”,visible=true)
@JsonSubTypes({
@JsonSubTypes.Type(value=TicketMovedEvent.class,name=“TicketMovedEvent”)
})
公共类票务{
...
//现在缺少“type”属性
})
JSON现在是正确的:

{
        ...
    "type": "TicketMovedEvent",
        ...
}
我希望,通过遵循OpenAPI3.x准则,生成的类能够正确地序列化/反序列化

(旁注)

在反序列化过程中,通过使用上述方法,可能会出现以下错误:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" (class it.blutec.bludesk.web.api.model.TicketMovedEvent), not marked as ignorable ...
要解决此问题,需要将Jackson ObjectMapper对象配置为忽略此类情况

ObjectMapper om=new ObjectMapper().configure(反序列化功能.FAIL_ON_UNKNOWN_属性,false)

我自己也遇到了这个问题。在OpenApi属性列表中不包含鉴别器字段确实解决了序列化时的双字段问题,同时在反序列化时导致无法识别的属性异常。
经过一些尝试和错误,我发现第二个问题可以通过删除生成代码中
@JsonTypeInfo
注释的
“visible=true”
属性(或将其设置为false)来解决。(如果您的构建过程设置总是从openapi规范重新生成代码,那么当然,这不是一个真正的解决方案)。

我相信我解决了这个问题,应该在openapi generator 4.3发行版中发布。请随意查看它(由于该PR,支持之一也应该得到极大改进).

我遇到了同样的问题。问题在于生成的模型类上的
@JsonTypeInfo
注释

其生成为-

@JsonTypeInfo(... include = JsonTypeInfo.As.PROPERTY ...)
这将在模型中添加一个额外的属性

如果我在生成的代码中将其更改为-

@JsonTypeInfo(... include = JsonTypeInfo.As.EXISTING_PROPERTY ...)
它使用模型中已经存在的属性,并且一切正常

但是,当我重新生成代码时,这个更改当然会丢失。
如果有人找到了一个永久的解决方案,那就太好了。

在openapi生成器存储库中打开一个问题@Helen Thank:我遇到了一个类似的问题(虽然我没有使用openapi,只是简单的Jackson,我完全控制了源代码)。如果我没记错的话,修复方法是使用
JsonTypeInfo.As.EXISTING_属性
而不是
JsonTypeInfo.As.PROPERTY
@cassiomolin我已经尝试用
JsonTypeInfo.As.EXISTING_属性
手动重写生成的类,这就是“鉴别器”在JSON中只出现一次,但它有
null
值。我认为这与为Spring生成的代码有关,实际上我正试图在openapi生成器repo中找到一些线索。谢谢。是的,问题取决于生成过程。手动编辑生成的类可以是一种解决方法,但我希望是这样最终修复。如果你想跟踪这个问题,这里是GitHub链接:我已经尝试了4.3.0-SNAPSHOT(在我的机器上构建),带有“spring”目标,但discriminator属性仍在生成的类中。我的建议是避免在类中生成discriminator属性,因为由于(Jackson)的原因,此信息已经存在
JsonTypeInfo
annotation。我为此打开了一个问题:没错。一年前,我打开了一个,如果你想跟踪这个问题的话。我看到有人合并了一个PR-它将类型信息批注更改为现有属性。是的,但这似乎不适用于此问题。请检查我的。无论如何,我会再试一次在中。(我在上面的评论中支持
现有的_属性
解决方案,因为我忘了它对我不起作用)