Repository navigation
[Java][Spring] useRecords: allOf families as an interface and flat records - #25492
Sekator778 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
1 issue found across 22 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/openapi3/server/petstore/spring-boot-4-records/src/main/java/org/openapitools/model/Child.java">
<violation number="1" location="samples/openapi3/server/petstore/spring-boot-4-records/src/main/java/org/openapitools/model/Child.java:43">
P3: The builder Javadoc is inaccurate for this record: unset components are passed to the canonical constructor as `null`, because `Child` has no compact constructor defaults. Reword it to state that unset components are null, or have the generator emit this sentence only when defaults exist. Since this file is generated, the fix belongs in the SpringCodegen record template.</violation>
</file>
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
View guided diff | Re-trigger cubic
| /** | ||
| * Get x | ||
| * @return x | ||
| * Builder of Child. Components that are not set get their initial value from the constructor. |
There was a problem hiding this comment.
P3: The builder Javadoc is inaccurate for this record: unset components are passed to the canonical constructor as null, because Child has no compact constructor defaults. Reword it to state that unset components are null, or have the generator emit this sentence only when defaults exist. Since this file is generated, the fix belongs in the SpringCodegen record template.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/openapi3/server/petstore/spring-boot-4-records/src/main/java/org/openapitools/model/Child.java, line 43:
<comment>The builder Javadoc is inaccurate for this record: unset components are passed to the canonical constructor as `null`, because `Child` has no compact constructor defaults. Reword it to state that unset components are null, or have the generator emit this sentence only when defaults exist. Since this file is generated, the fix belongs in the SpringCodegen record template.</comment>
<file context>
@@ -21,151 +21,73 @@
/**
- * Get x
- * @return x
+ * Builder of Child. Components that are not set get their initial value from the constructor.
+ * The builder can be used again after {@link #build()}.
*/
</file context>
| * Builder of Child. Components that are not set get their initial value from the constructor. | |
| * Builder of Child. Components that are not set are passed to the constructor as null. |
40ffbde to
18351c4
Compare
UnderHear
left a comment
There was a problem hiding this comment.
Could x-field-extra-annotation be kept off the new interface accessors? For an otherwise eligible allOf family, a parent property with x-field-extra-annotation: '@example.FieldOnly', where FieldOnly is declared with @Target(ElementType.FIELD), was valid on the field emitted by pojo.mustache. This template now emits it on a method such as @example.FieldOnly String name();, which is not a valid annotation target and prevents the generated family from compiling. The child record component can still carry that annotation for its backing field; copying it onto the parent interface method is the new failure. Please keep field-only metadata on the record components (or retain a class fallback when necessary), and cover a field-target-only annotation in an eligible family.
AI-assisted source review; I have not generated or compiled this example.
18351c4 to
d8c7111
Compare
…cords A parent with a discriminator of its own, whose children extend it one level down, becomes an interface that keeps the type-info annotations and declares an annotated accessor for each property (sealed with useSealed). Each child becomes a record of all properties in the class's order that implements the parent and the oneOf interfaces it implements today, and its builder covers all components. The family is decided as a whole: a deeper hierarchy, a child that redeclares a parent property, a parent without a discriminator of its own, with additionalProperties, a oneOf or anyOf composition, a oneOf membership or a mapping to itself, a member bound from request parameters, or any member with another reason to stay a class keeps every member a class, and the log names the parent and the cause.
d8c7111 to
cd02369
Compare
Sixth step towards #10490, allOf. With
useRecords, a family one level below a parent with a discriminator becomes an interface for the parent, keeping the type-info block, and a flat record per child. A family that cannot, such as one with a redeclared property, stays classes and the reason is logged. Unlike the class, the parent can no longer be read under its own name.@cachescrubber @welshm @MelleD @atextor @manedev79 @javisst @borsch @banlevente @Zomzog @martin-mfg @KannaKim
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
Summary by cubic
Continues the
useRecordswork by turning allOf families into interfaces and flat records. A parent with a discriminator whose children extend it one level down becomes a sealed (withuseSealed) interface that keeps the type-info annotations and declares an annotated accessor for each property; each child becomes a record that implements the parent and the oneOf interfaces it already implements, contains all family properties, and has a builder covering all components. Families that cannot be represented this way (a deeper hierarchy, a redeclared property, a parent without a discriminator of its own, withadditionalProperties, a child mapped back to the parent or sharing a Java name with the discriminator, a request-parameter member, and others) stay classes, and the log names the parent and the cause.The parent can no longer be deserialized under its own name; only the children records are usable as JSON payloads.
Written for commit cd02369. Summary will update on new commits.