diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index d000cde76814..97e6d8735e43 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -574,6 +574,14 @@ public Map postProcessAllModels(Map objs) } // if this is oneOf interface, make sure we include the necessary imports for it addImportsToOneOfInterface(modelsImports); + // + // ensure that no JsonTypeName is created when the parent interface has a discriminator mapping + if (cm.discriminator != null && cm.discriminator.getMappedModels() != null && !cm.discriminator.getMappedModels().isEmpty()) { + cm.discriminator.getMappedModels().stream() + .map(MappedModel::getModel) + .filter(Objects::nonNull) + .forEach(model -> model.setHasDiscriminatorWithNonEmptyMapping(true)); + } } } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java index 14b541cf9f0c..c46b8dfdfa10 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java @@ -8132,4 +8132,21 @@ void schemaMappingWithNullableAllOfRendersNullableJavaProperty() throws IOExcept JavaFileAssert.assertThat(files.get("MyObject.java")) .assertProperty("optionalRef").withType("JsonNullable"); } + + @Test + void issue24003() throws IOException { + Map files = generateFromContract( + "src/test/resources/3_0/spring/issue_24003.yaml", SPRING_BOOT, + Map.of(USE_SPRING_BOOT4, true, MODEL_NAME_SUFFIX, "DTO", INTERFACE_ONLY, "true")); + JavaFileAssert.assertThat(files.get("BrLockDTO.java")).isInterface() + .assertTypeAnnotations() + .containsWithNameAndAttributes("JsonTypeInfo", Map.of("use", "JsonTypeInfo.Id.NAME", "include", "JsonTypeInfo.As.PROPERTY", "property", "\"lockType\"", "visible", "true")) + .containsWithName("JsonSubTypes") + .recursivelyContainsWithNameAndAttributes("JsonSubTypes.Type", Map.of("value", "ComponentBrLockDTO.class", "name", "\"COMPONENT\"")) + .recursivelyContainsWithNameAndAttributes("JsonSubTypes.Type", Map.of("value", "UserBrLockDTO.class", "name", "\"USER\"")); + JavaFileAssert.assertThat(files.get("ComponentBrLockDTO.java")).implementsInterfaces("BrLockDTO") + .fileDoesNotContain("@JsonTypeName"); + JavaFileAssert.assertThat(files.get("UserBrLockDTO.java")).implementsInterfaces("BrLockDTO") + .fileDoesNotContain("@JsonTypeName"); + } } \ No newline at end of file diff --git a/modules/openapi-generator/src/test/resources/3_0/spring/issue_24003.yaml b/modules/openapi-generator/src/test/resources/3_0/spring/issue_24003.yaml new file mode 100644 index 000000000000..21a6cc06ae30 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/spring/issue_24003.yaml @@ -0,0 +1,68 @@ +openapi: 3.0.1 +info: + title: x-discriminator-value JsonTypeName bug + version: 1.0.0 +paths: + /locks: + get: + operationId: getLocks + responses: + '200': + description: list of locks + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/BrLock' +components: + schemas: + LockType: + type: string + enum: + - USER + - COMPONENT + + BrLock: + type: object + required: + - lockType + properties: + lockType: + $ref: '#/components/schemas/LockType' + oneOf: + - $ref: '#/components/schemas/UserBrLock' + - $ref: '#/components/schemas/ComponentBrLock' + discriminator: + propertyName: lockType + mapping: + USER: '#/components/schemas/UserBrLock' + COMPONENT: '#/components/schemas/ComponentBrLock' + + BaseBrLock: + type: object + required: + - lockType + properties: + lockType: + $ref: '#/components/schemas/LockType' + + UserBrLock: + allOf: + - $ref: '#/components/schemas/BaseBrLock' + - type: object + required: + - userId + properties: + userId: + type: string + + ComponentBrLock: + allOf: + - $ref: '#/components/schemas/BaseBrLock' + - type: object + required: + - componentId + properties: + componentId: + type: string \ No newline at end of file