Skip to content

fix: keep oneOf when WRAPPER_OBJECT wrapping is applied - #5331

Open
vpelikh wants to merge 1 commit into
swagger-api:3.0.0from
vpelikh:upstream-pr-1-wrapper-object
Open

vpelikh wants to merge 1 commit into
swagger-api:3.0.0from
vpelikh:upstream-pr-1-wrapper-object

Conversation

@vpelikh

@vpelikh vpelikh commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

A schema that already carries a oneOf now keeps it when Jackson's WRAPPER_OBJECT type info is applied. Previously the composition was silently dropped and the schema became a plain object with a single property.

Problem

ModelResolver.resolveWrapping(...) builds a new wrapper schema and nests the model inside it:

Schema wrapperSchema = openapi31 ? new JsonSchema().typesItem("object") : new ObjectSchema();
wrapperSchema.name(model.getName());
wrapperSchema.addProperties(name, model);
return wrapperSchema;

The wrapper copies only the name and the single property. If model had a oneOf (from @Schema(oneOf = ...), @Schema(subTypes = ...) or @JsonSubTypes), it is lost: the returned schema is an ObjectSchema, not a ComposedSchema, and the oneOf is gone.

Reproduction (@JsonTypeInfo(include = WRAPPER_OBJECT) + @Schema(oneOf)):

result
before ObjectSchema, properties [Pet], no oneOf
after ComposedSchema, oneOf = 2 refs, wrapper property present

Change

When the model already has a non-empty oneOf, add the wrapper property directly to the model and return it, instead of nesting it in a wrapper schema:

if (model.getOneOf() != null && !model.getOneOf().isEmpty()) {
    model.addProperties(name, newObjectSchema());
    return model;
}

The empty-object-schema expression was already used once in this method, so instead of repeating it a second time it is extracted to a small helper:

/** An empty object schema for the current OpenAPI version. */
private Schema newObjectSchema() {
    return openapi31 ? new JsonSchema().typesItem("object") : new ObjectSchema();
}

Behavior is unchanged for models without oneOf.

Tests

Adds WrapperObjectOneOfTest. It fails before the change (ObjectSchema with no oneOf) and passes after it.

Notes

This is the small stack split out of #5320. It is a standalone bug fix, reproducible on unmodified 3.0.0, and does not depend on @JsonSubTypes work.

ModelResolver.resolveWrapping() nested the whole model inside a new wrapper
schema that only copied the name and properties, so a model carrying a oneOf
(from @Schema(oneOf) or @JsonSubTypes) lost its composition and became a plain
object schema with a single property.

When the model already has a non-empty oneOf, add the wrapper property
directly to the model and return it, preserving the composition. Behavior is
unchanged for models without oneOf.

Adds WrapperObjectOneOfTest, which fails before the fix (ObjectSchema with no
oneOf) and passes after it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant