Skip to content

[BUG][JAVA][SPRING] Regression in 6.5.0 and later when generating DTOs with xml support #16915

Description

@tomyy

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

After upgrading from open-api-generator 6.4.0 to 6.5.0 the Spring generator creates invalid DTOs if the option "withXml" is set to true. The problem also exists on the latest master.

Trying to serialize the generated DTOs fails with the following exception:
Failed to evaluate Jackson serialization for type [class x.y.z.Testannotations]: java.lang.IllegalStateException: Conflicting/ambiguous property name definitions (implicit name 'prop'): found multiple explicit names: [{}prop, prop], but also implicit accessor: [method x.y.z.Testannotations#setProp(java.lang.String)][visible=true,ignore=false,explicitName=false]

openapi-generator version

6.5.0 or later
Regression from 6.4.0

OpenAPI declaration file content or url

The linked gist contains the OpenAPI declaration, a Main.java that shows the exception occuring at runtime and a build.gradle for building and executing the test (gradle exec)

https://gist.github.com/tomyy/5d18dd5cdb6cca37131f1e6b7d8c6893

Generation Details
generatorName: spring
library: spring-boot
inputSpec: test.yaml
outputDir: generated
additionalProperties:
  interfaceOnly: "true"
  withXml: "true"
  openApiNullable: "false"
  useSpringBoot3: "true"

(Hopefully correctly translated from the provided gradle build script)

Steps to reproduce

Create an API for Spring with the option "withXml". Try to serialize a response object as XML using the Jackson XmlMapper.

Actual Result
Jackson throws an exception:
Exception in thread "main" java.lang.IllegalStateException: Conflicting/ambiguous property name definitions (implicit name 'prop'): found multiple explicit names: [{}prop, prop], but also implicit accessor: [method x.y.z.Testannotations#setProp(java.lang.String)][visible=true,ignore=false,explicitName=false]

Expected Result
The response object is successfully serialized into an XML.

Related issues/PRs

This problem is caused by the following change:

Analysis

The change to the JavaSpring/pojo.mustache template has the effect that when withXml is set to true there are two Jackson annotations on the generated model:

  • a @JacksonXmlProperty annotation on the field
  • a @JsonProperty annotation on the getter
    This causes Jackson to fail when serializing to XML.

Some might consider this a bug in Jackson.

But still the OpenAPI generator should consequently either annotate the field or the getter.

Suggest a fix

Change the template JavaSpring/pojo.mustache so that the Jackson-Annotations are both on the getter:

diff --git a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache
index c449fae1873..5fe61163d48 100644
--- a/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache
+++ b/modules/openapi-generator/src/main/resources/JavaSpring/pojo.mustache
@@ -48,11 +48,6 @@ public class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}{{^parent}}
     {{/mostInnerItems}}
     {{/isContainer}}
     {{/isEnum}}
-  {{#jackson}}
-  {{#withXml}}
-  @JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}localName = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
-  {{/withXml}}
-  {{/jackson}}
   {{#gson}}
   @SerializedName("{{baseName}}")
   {{/gson}}
@@ -199,6 +194,9 @@ public class {{classname}}{{#parent}} extends {{{parent}}}{{/parent}}{{^parent}}
   {{/swagger1AnnotationLibrary}}
   {{#jackson}}
   @JsonProperty("{{baseName}}")
+  {{#withXml}}
+  @JacksonXmlProperty({{#isXmlAttribute}}isAttribute = true, {{/isXmlAttribute}}{{#xmlNamespace}}namespace="{{.}}", {{/xmlNamespace}}localName = "{{xmlName}}{{^xmlName}}{{baseName}}{{/xmlName}}")
+  {{/withXml}}
   {{/jackson}}
   {{#deprecated}}
   @Deprecated

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions