-
-
Notifications
You must be signed in to change notification settings - Fork 7.4k
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
The generated DTO looks something like this (simplified). The issue is that JSpecify's @Nullable cannot be placed before a fully qualified type name. The annotation must appear directly before the simple type name.
When the OpenAPI generator uses schema mappings, it references types by their fully qualified name instead of adding an import, which makes @Nullable placement invalid. This affects all usages of the type like fields, getters, setters, and constructors.
The fix would be to have the generator add proper imports and use simple type names instead. This would work in most cases, but breaks down if two schema-mapped types share the same simple name, then the generator would need to fall back to fully qualified names for one of them, reintroducing the problem.
public class MyDto implements Serializable {
private static final long serialVersionUID = 1L;
private @Nullable a.b.c.PersonCountValue men; // Doesn't work, current behavior
private a.b.c.@Nullable PersonCountValue women; // Works
}[ERROR] /path/a/b/c/MyDto.java type annotation @org.jspecify.annotations.Nullable is not expected here
openapi-generator version
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.20.0</version>OpenAPI declaration file content or url
my-api-specification.yaml
components:
schemas:
MyDto:
type: object
properties:
men:
$ref: '#/components/schemas/PersonCountValue'
women:
$ref: '#/components/schemas/PersonCountValue'
PersonCountValue:
type: number
format: personCountValue
example: 1234my-api-config.yaml
schemaMappings:
PersonCountValue: a.b.c.PersonCountValueand then of course you need to set the config file in the generator with something like this
<configurationFile>
${project.basedir}/src/main/resources/static/my-api-config.yaml
</configurationFile>Then no class for PersonCountValue will be generated but instead an existing class managed by yourself will be used for the type.
Generation Details
Using Java 25 with Maven
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator-maven-plugin.version}</version>
<configuration>
<generatorName>spring</generatorName>
<library>spring-boot</library>
<generateSupportingFiles>false</generateSupportingFiles>
<generateModelTests>false</generateModelTests>
<importMappings>
<importMapping>Nullable=org.jspecify.annotations.Nullable</importMapping>
</importMappings>
<generateApiTests>false</generateApiTests>
<configOptions>
<interfaceOnly>true</interfaceOnly>
<oas3>true</oas3>
<openApiNullable>false</openApiNullable>
<serializableModel>true</serializableModel>
<skipDefaultInterface>true</skipDefaultInterface>
<useResponseEntity>true</useResponseEntity>
<useSpringBoot4>true</useSpringBoot4>
<useJackson3>true</useJackson3>
<useSpringController>true</useSpringController>
<useTags>true</useTags>
<useBeanValidation>false</useBeanValidation>
</configOptions>
</configuration>
</plugin>Steps to reproduce
Generate a Dto with a SchemaMapping type, which then will be written as package.name.Type instead of importing.
Suggest a fix
There needs to be a check, that when the type is not imported, that the annotation has to be right before the type and after the package name, like its shown in my example generated Dto above