[Java][Spring] Emit @Nullable on non-required fields with a default value under jspecify (#24294)#24338
Conversation
…alue under jspecify (OpenAPITools#24294) Under jspecify, a non-required model field carrying a `default` value was generated without the `@Nullable` annotation. A non-required field is nullable regardless of its default, because the caller can still explicitly pass null. The JavaSpring `nullableAnnotation` partial gated the annotation behind `isNullable` in its `defaultValue` branch, suppressing @nullable for the common case (non-required + default + openApiNullable=false). This scopes the fix to `useJspecify` so defaulted non-required fields are treated the same as non-defaulted ones, while leaving the non-jspecify path byte-for-byte unchanged. Adds a regression test (testJspecifyNullableWithDefaultValue_issue24294) with a minimal spec. Full SpringCodegenTest suite passes (290 tests, 0 failures).
There was a problem hiding this comment.
All reported issues were addressed across 3 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
Note that I have not used the Spring generator myself, so I do not know how it compares to other languages with regard to how it handles nullability. From an OAS perspective, isn't this new annotation incorrect? Having force:
type: boolean
default: falsein OAS 3.0 where the property is not required explicitly states that we either expect The specification basically states if it is a general issue that most generators and languages do not differentiate between |
… request params The previous change made every non-required field with a default value @nullable under jspecify. Because nullableAnnotation.mustache is shared between POJO model fields and Spring controller parameters, this incorrectly annotated non-required query/header/cookie/path/body/form parameters that declare a default value. Those parameters are non-null at runtime: Spring's @RequestParam/@RequestHeader/ @CookieValue supply the configured defaultValue when the request value is absent, so @nullable is a wrong nullness contract for them. Restrict the new behavior to model properties (identified by the absence of the CodegenParameter isXxxParam flags). Parameter rendering is unchanged from before this fix. Extends the regression test with a non-required query param carrying a default (must not be @nullable) alongside one without a default (stays @nullable). Full SpringCodegenTest suite passes (290 tests, 0 failures).
|
Fair point on OAS semantics — strictly, non-required without Two reasons I'd keep the annotation here:
The deeper missing-vs-null tri-state question is real, but it's a generator-wide design change (every non-required field, every Java target, breaking) — better as a separate issue, which I'm happy to open. |
[Java][Spring] Emit @nullable on non-required fields with a default value under jspecify (#24294)
Under jspecify, a non-required model field carrying a
defaultvalue was generated without the@Nullableannotation. A non-required field is nullable regardless of its default, because the caller can still explicitly pass null.The JavaSpring
nullableAnnotationpartial gated the annotation behindisNullablein itsdefaultValuebranch, suppressing @nullable for the common case (non-required + default + openApiNullable=false). This scopes the fix touseJspecifyso defaulted non-required fields are treated the same as non-defaulted ones, while leaving the non-jspecify path byte-for-byte unchanged.Adds a regression test (testJspecifyNullableWithDefaultValue_issue24294) with a minimal spec. Full SpringCodegenTest suite passes (290 tests, 0 failures).
Summary by cubic
Emit
@Nullablefor non-required model properties that have a default whenuseJspecifyis enabled, and keep Spring request parameters with defaults non-null. Fixes missing nullability on defaulted properties while keeping parameter rendering and non-jspecify behavior unchanged.JavaSpring/nullableAnnotation.mustacheto apply@Nullableonly to defaulted, non-required model fields (excludeisQueryParam/isHeaderParam/isCookieParam/isPathParam/isBodyParam/isFormParam; still respectopenApiNullableanduseOptional).testJspecifyNullableWithDefaultValue_issue24294with a minimal spec to verifyorg.jspecify.annotations.Nullableon defaulted model fields (not on required), and to ensure request parameters with defaults are not annotated while those without defaults remain annotated.Written for commit 2ff022f. Summary will update on new commits.