OpenAPITools / OpenAPITools/openapi-generator
[BUG] [JAVA] Broken constructors in subclasses when superclass has read only properties
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 (example)?
- 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
With the Java client generator, models which have read only properties and which are used as superclasses via allOf polymorphism do not have setters generated, which makes sense, and the properties are of course private. However subclasses are generated incorrectly. Their constructors, which take all read only properties as arguments, contain code to set the private members of the superclass, and hence will not compile.
I am using the jersey2 library; issue may be present in others as well (did not test others.)
openapi-generator version
Using 5.4.0. Issue also exists in 6.0.1 as well as in latest master.
OpenAPI declaration file content or url
components:
schemas:
# Pet has a readonly name property
Pet:
type: object
discriminator:
propertyName: discriminator
required:
- name
- discriminator
properties:
name:
type: string
readOnly: true
discriminator:
type: string
# Dog has a readonly packSize property.
# Readonly properties do not get setters, and all properties are private in the implementing class.
# Dog's generated constructor sets the name property, but it is private in Pet superclass.
Dog:
description: A representation of a dog
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
properties:
packSize:
type: integer
format: int32
description: the size of the pack the dog is from
default: 1
minimum: 1
readOnly: true
required:
- packSize
full openapi.yaml for repro available here: https://gist.github.com/pbarnes-tibco/b284210a1670b30fc60a6e7db3a9637a
Generation Details
openapi-generator-cli generate -g java --library jersey2 -i ./openapi.yaml -o ./generated/openapiclient
Steps to reproduce
Create a model which has read only properties, and a second model inheriting from the first via allOf polymorphism as in the above yaml. Generate Java client stubs with jersey2 library. Observe the generated code for the Dog class constructor:
public class Dog extends Pet {
// ...
@JsonCreator
public Dog(
@JsonProperty(JSON_PROPERTY_PACK_SIZE) Integer packSize,
@JsonProperty(JSON_PROPERTY_NAME) String name) {
this();
this.packSize = packSize;
this.name = name; // <<<<< name is private in Pet class
}
Related issues/PRs
None
Suggest a fix
Ideally, the derived class would call the appropriate superclass constructor. Alternatively, could generate protected setters for read only properties and call them instead.
To workaround, I'm using a custom template which generates protected setters and calls them instead, available here: https://gist.github.com/pbarnes-tibco/9bfe44e0a6998456005de577cf1f625e
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
Start by running the shown openapi-generator-cli command with the provided Pet and Dog allOf schema, then inspect the generated Dog and Pet constructors for the private superclass-property assignment. Determine how the Java jersey2 templates handle read-only inherited properties; done means the generated client compiles and the reproduction no longer assigns superclass-private fields directly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, openapi
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100