OpenAPITools / OpenAPITools/openapi-generator
[BUG] [JAVA] Missing FQCN when using 2 datatypes with the same name
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue from the provided OpenAPI declaration and inspect Java model generation and type/import resolution. Done means SameNamedDatatypes distinguishes the custom String schema from Java's built-in String using fully qualified names, with a regression test covering both datatypes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100