[kotlin-server] fix: discriminator serialized twice (use As.EXISTING_PROPERTY)
IN
8h ago+17+17+01234567890123456789-7-7-0123456789
Fixes #25524.
kotlin-server rendered @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 — KotlinServerCodegen guarantees that by always adding/updating the property on each mapped child. Jackson therefore serialized the discriminator twice (As.PROPERTY injects 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).- Extended the existing
oneOfWithDiscriminatorunit test to assertAs.EXISTING_PROPERTYis rendered (andAs.PROPERTYis not). - Regenerated all 16
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).- The issue reporter verified the same change locally: serialization now emits
{"kind":"CAT","lives":9}instead of the duplicated key.
PR checklist
- Read the contribution guidelines.
- Regenerated the affected samples via
./bin/generate-samples.sh(allkotlin-serverconfigs); no files deleted. - Pull request is created against the
masterbranch.
Summary by cubic
Fixes duplicated discriminator keys in kotlin-server polymorphic models by reusing the existing property instead of injecting a copy, and makes the discriminator visible on deserialization so round-trips preserve it.
- Switches
typeInfoAnnotation.mustachetoAs.EXISTING_PROPERTYso Jackson serializes the discriminator once, not twice. - Emits
visible = trueunconditionally so deserialized children (including thefixJacksonJsonTypeInfoInheritance=falsepath) keep their discriminator property populated. - Updates the
oneOfWithDiscriminatortests to assert the new include type andvisible = true. - Regenerates
kotlin-serversamples; only three polymorphism-relatedPet.ktfiles change.