Repository navigation
Conversation
…info Every mapped child model declares or inherits the discriminator property (KotlinServerCodegen guarantees that), so As.PROPERTY made Jackson serialize the discriminator twice - once injected, once as the regular property - producing invalid JSON with a duplicated key. Fixes OpenAPITools#25524
There was a problem hiding this comment.
1 issue found across 5 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt">
<violation number="1" location="samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt:20">
P2: `As.EXISTING_PROPERTY` now makes serialization depend on the caller-supplied `petType`, but these allOf child models accept any string rather than defaulting or constraining it to `Cat`/`Dog`. A `Cat` with another value emits an unmappable discriminator and cannot round-trip through `Pet`; generate subtype-specific defaults/constants for these children or otherwise ensure the existing property always contains the mapped subtype value before using this mode.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
| * @param petType | ||
| */ | ||
| @com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY, property = "petType", visible = true) | ||
| @com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.EXISTING_PROPERTY, property = "petType", visible = true) |
There was a problem hiding this comment.
P2: As.EXISTING_PROPERTY now makes serialization depend on the caller-supplied petType, but these allOf child models accept any string rather than defaulting or constraining it to Cat/Dog. A Cat with another value emits an unmappable discriminator and cannot round-trip through Pet; generate subtype-specific defaults/constants for these children or otherwise ensure the existing property always contains the mapped subtype value before using this mode.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/server/others/kotlin-server/polymorphism-allof-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt, line 20:
<comment>`As.EXISTING_PROPERTY` now makes serialization depend on the caller-supplied `petType`, but these allOf child models accept any string rather than defaulting or constraining it to `Cat`/`Dog`. A `Cat` with another value emits an unmappable discriminator and cannot round-trip through `Pet`; generate subtype-specific defaults/constants for these children or otherwise ensure the existing property always contains the mapped subtype value before using this mode.</comment>
<file context>
@@ -17,7 +17,7 @@ package org.openapitools.server.models
* @param petType
*/
-@com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY, property = "petType", visible = true)
+@com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.EXISTING_PROPERTY, property = "petType", visible = true)
@com.fasterxml.jackson.annotation.JsonSubTypes(
com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Cat::class, name = "Cat"),
</file context>
There was a problem hiding this comment.
Same fix as above thread — see the reply there (fde104a makes the property authoritative via visible=true).
With As.EXISTING_PROPERTY the discriminator is read from and written to the real property that every mapped child model declares or inherits. Emit visible=true unconditionally so the property is also populated on deserialization - otherwise a deserialized child (in the fixJacksonJsonTypeInfoInheritance=false path) would serialize without its discriminator. This is the canonical Jackson pattern for a discriminator modeled as a real property. Addresses review feedback in OpenAPITools#25543.
Fixes #25524.
kotlin-serverrendered@JsonTypeInfo(..., include = As.PROPERTY, property = "kind", visible = ...)on the parent class of a polymorphic hierarchy, while every mapped child model also declares (or inherits) the discriminator property —KotlinServerCodegenguarantees that by always adding/updating the property on each mapped child. Jackson therefore serialized the discriminator twice (As.PROPERTYinjects it, plus the regular property), producing invalid JSON like{"kind":"CAT","kind":"CAT","lives":9}.What changed
kotlin-server/typeInfoAnnotation.mustache:As.PROPERTY→As.EXISTING_PROPERTY, so Jackson reuses the already-declared discriminator property instead of injecting a synthetic copy (one-token change, as suggested in the issue).oneOfWithDiscriminatorunit test to assertAs.EXISTING_PROPERTYis rendered (andAs.PROPERTYis not).kotlin-serversample configs; the only content changes are the three polymorphism samples'Pet.ktannotation line.Verification
KotlinServerCodegenTest: 30 tests, 0 failures (covers oneOf and allOf hierarchies, sealed-class parent, and thefixJacksonJsonTypeInfoInheritance=falsescenario).{"kind":"CAT","lives":9}instead of the duplicated key.PR checklist
./bin/generate-samples.sh(allkotlin-serverconfigs); no files deleted.masterbranch.Summary by cubic
Fixes duplicated discriminator keys in
kotlin-serverpolymorphic models by reusing the existing property instead of injecting a copy, and makes the discriminator visible on deserialization so round-trips preserve it.typeInfoAnnotation.mustachetoAs.EXISTING_PROPERTYso Jackson serializes the discriminator once, not twice.visible = trueunconditionally so deserialized children (including thefixJacksonJsonTypeInfoInheritance=falsepath) keep their discriminator property populated.oneOfWithDiscriminatortests to assert the new include type andvisible = true.kotlin-serversamples; only three polymorphism-relatedPet.ktfiles change.Written for commit fde104a. Summary will update on new commits.