Skip to content

BeanOutputConverter .entity() ignores @Schema annotations despite documentation claiming support - forces code duplication with @JsonPropertyDescription #5341

@mustafagoksever

Description

@mustafagoksever

The BeanOutputConverter (used internally by .entity()) ignores Swagger/OpenAPI @Schema annotations for field descriptions, despite the official API documentation explicitly listing @Schema as a supported annotation. This forces developers to duplicate field descriptions using @JsonPropertyDescription, creating unnecessary code duplication and maintenance overhead.

Environment

  • Spring AI version: 1.1.2
  • Java version: Java 21
  • AI Provider: OpenAI

Documentation vs. Reality

According to the JsonSchemaGenerator API documentation, the following annotations are officially supported:

  • @ToolParam(required = ..., description = ...)
  • @JsonProperty(required = ...)
  • @JsonClassDescription(...)
  • @JsonPropertyDescription(...)
  • @Schema(required = ..., description = ...)
  • @Nullable

However, in practice with .entity() / BeanOutputConverter, only @JsonPropertyDescription actually works.


Steps to Reproduce

  1. Create a POJO with @Schema annotations:
import io.swagger.v3.oas.annotations.media.Schema;

public class Product {
    @Schema(description = "Unique product identifier")
    private Long id;
    
    @Schema(description = "Product name as displayed in catalog")
    private String name;
    
    @Schema(description = "Product price in USD")
    private Double price;
    
    // getters and setters
}
  1. Use structured output with .entity():
Product result = chatClient.prompt()
    .user("Extract product information: iPhone 15 Pro, $999")
    .call()
    .entity(Product.class);
  1. Debug the generated schema:
BeanOutputConverter<Product> converter = new BeanOutputConverter<>(Product.class);
System.out.println(converter.getFormat());

Expected Behavior

The generated JSON schema should include description fields from @Schema annotations:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "description": "Unique product identifier"
    },
    "name": {
      "type": "string",
      "description": "Product name as displayed in catalog"
    },
    "price": {
      "type": "number",
      "description": "Product price in USD"
    }
  }
}

Actual Behavior

The generated schema completely omits all description fields:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id": {"type": "integer"},
    "name": {"type": "string"},
    "price": {"type": "number"}
  }
}

Current Workaround (Code Duplication Problem)

The only way to make descriptions work is to use @JsonPropertyDescription:

import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import io.swagger.v3.oas.annotations.media.Schema;

public class Product {
    // For OpenAPI/Swagger documentation
    @Schema(description = "Unique product identifier")
    
    // For Spring AI structured output - DUPLICATE!
    @JsonPropertyDescription("Unique product identifier")
    private Long id;
    
    @Schema(description = "Product name as displayed in catalog")
    @JsonPropertyDescription("Product name as displayed in catalog")
    private String name;
    
    @Schema(description = "Product price in USD")
    @JsonPropertyDescription("Product price in USD")
    private Double price;
}

This creates several problems:

  1. Code duplication - Same description text written twice on every field
  2. Maintenance burden - Description changes must be updated in two places
  3. Inconsistency risk - Descriptions can drift out of sync between annotations
  4. Documentation mismatch - Contradicts the official API documentation that claims @Schema is supported
  5. Ecosystem fragmentation - Forces different annotation strategies for OpenAPI docs vs AI structured outputs

Impact

This issue affects any Spring Boot application that uses both:

  • OpenAPI/Swagger for API documentation (@Schema)
  • Spring AI for structured outputs (.entity())

These are very common use cases in modern Spring Boot applications, making this a significant pain point.


Related Issues

Both issues point to inconsistencies in JsonSchemaGenerator's annotation handling.


Proposed Solution

Ensure JsonSchemaGenerator.internalGenerateFromClass includes the Swagger/OpenAPI module in its schema generation configuration, making @Schema annotations work consistently across:

  • Function calling / tool parameters
  • MCP tool schemas
  • Structured outputs via .entity() / BeanOutputConverter ← Currently broken

This would allow developers to use a single, consistent annotation strategy across their entire codebase.


Additional Context

Many Spring Boot developers already use @Schema extensively for OpenAPI documentation. Having to duplicate these annotations with @JsonPropertyDescription just for AI structured outputs creates unnecessary friction and goes against DRY principles.

The documentation explicitly states @Schema is supported, so this appears to be a bug rather than an intended limitation.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions