Skip to content

[BUG] [JAVA] Missing FQCN when using 2 datatypes with the same name #23234

@felldo

Description

@felldo

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When using for example a built in Java type like String and generating an own POJO also named String, then no import is being added for your custom datatype as well not for javas built in String type.

In the example below, I have declared two types: one named 'String' and another named 'SameNamedDatatypes'. However, this POJO does not contain any import statements or packages for either of the string types, and uses the same data type for both, even though they should be different.

openapi-generator version

latest master branch as of 13.03.2026

OpenAPI declaration file content or url
components:
  schemas:
    SameNamedDatatypes:
      type: object
      properties:
        customString:
          $ref: '#/components/schemas/String'
        normalString:
          nullable: true
          type: string
    String:
      type: object
      properties:
        placeholder:
          nullable: true
          type: string
Generation Details
package org.openapitools.model;

import java.net.URI;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import org.jspecify.annotations.Nullable;
import java.time.OffsetDateTime;
import jakarta.validation.constraints.NotNull;
import io.swagger.v3.oas.annotations.media.Schema;


import java.util.*;
import jakarta.annotation.Generated;

/**
 * SameNamedDatatypes
 */

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2026-03-13T23:59:14.006414300+01:00[Europe/Berlin]", comments = "Generator version: unset")
public class SameNamedDatatypes {

  private @Nullable String customString;

  private @Nullable String normalString = null;

  public SameNamedDatatypes customString(@Nullable String customString) {
    this.customString = customString;
    return this;
  }

  /**
   * Get customString
   * @return customString
   */
  
  @Schema(name = "customString", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("customString")
  public @Nullable String getCustomString() {
    return customString;
  }

  @JsonProperty("customString")
  public void setCustomString(@Nullable String customString) {
    this.customString = customString;
  }

  public SameNamedDatatypes normalString(@Nullable String normalString) {
    this.normalString = normalString;
    return this;
  }

  /**
   * Get normalString
   * @return normalString
   */
  
  @Schema(name = "normalString", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("normalString")
  public @Nullable String getNormalString() {
    return normalString;
  }

  @JsonProperty("normalString")
  public void setNormalString(@Nullable String normalString) {
    this.normalString = normalString;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    SameNamedDatatypes sameNamedDatatypes = (SameNamedDatatypes) o;
    return Objects.equals(this.customString, sameNamedDatatypes.customString) &&
        Objects.equals(this.normalString, sameNamedDatatypes.normalString);
  }

  @Override
  public int hashCode() {
    return Objects.hash(customString, normalString);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class SameNamedDatatypes {\n");
    sb.append("    customString: ").append(toIndentedString(customString)).append("\n");
    sb.append("    normalString: ").append(toIndentedString(normalString)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(@Nullable Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}
package org.openapitools.model;

import java.net.URI;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import org.jspecify.annotations.Nullable;
import java.time.OffsetDateTime;
import jakarta.validation.constraints.NotNull;
import io.swagger.v3.oas.annotations.media.Schema;


import java.util.*;
import jakarta.annotation.Generated;

/**
 * String
 */

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2026-03-13T23:59:14.006414300+01:00[Europe/Berlin]", comments = "Generator version: unset")
public class String {

  private @Nullable String placeholder = null;

  public String placeholder(@Nullable String placeholder) {
    this.placeholder = placeholder;
    return this;
  }

  /**
   * Get placeholder
   * @return placeholder
   */
  
  @Schema(name = "placeholder", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
  @JsonProperty("placeholder")
  public @Nullable String getPlaceholder() {
    return placeholder;
  }

  @JsonProperty("placeholder")
  public void setPlaceholder(@Nullable String placeholder) {
    this.placeholder = placeholder;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    String string = (String) o;
    return Objects.equals(this.placeholder, string.placeholder);
  }

  @Override
  public int hashCode() {
    return Objects.hash(placeholder);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class String {\n");
    sb.append("    placeholder: ").append(toIndentedString(placeholder)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(@Nullable Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}
Steps to reproduce

Generate the models from the OpenApi.yaml.

Suggest a fix

When this problem occurs, the only solution is to use a FQCN for both datatypes. Adding an import statement will not solve this, because then both datatypes would be of the same imported datatype

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