-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
[BUG] Code is not generated correctly for allOf. #6815
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
👍 Thanks for opening this issue! The team will review the labels and make any necessary changes. |
Looks like it's because of the (deprecated) support for this legacy case: if there is a single parent class, then it's treated as inheritance even though there is discriminator. Generator probably prints a "deprecated" message in the console when it happens. This special behavior is supposed to be removed in v5: #5876 (comment) |
There is no discriminator in this case. So I would expect that the standard
I like the inheritance actually, but this behavior seems to deviate from my reading of the semantics of I can live with the inheritance, but my point is that this seems to deviate from what |
Looking at // The parent model name from the schemas. The parent is determined by inspecting the allOf, anyOf and
// oneOf attributes in the OAS. First codegen inspects 'allOf', then 'anyOf', then 'oneOf'.
// If there are multiple object references in the attribute ('allOf', 'anyOf', 'oneOf'), and one of the
// object is a discriminator, that object is set as the parent. If no discriminator is specified,
// codegen returns the first one in the list, i.e. there is no obvious parent in the OpenAPI specification.
// When possible, the mustache templates should use 'allParents' to handle multiple parents.
public String parent, parentSchema; Notice
This does not seem complete to me. A parent seems to refer to an inheritance structure. An object should only have a parent if there is a I think that This seems to be the issue with composition vs inheritance. https://spec.openapis.org/oas/v3.0.3#composition-and-inheritance-polymorphism |
I agree it doesn't comply with the spec. I don't know the reasons for this special case to exist in the first place. But apparently it's been there for years. Perhaps will be removed in the next major release (although I'm not sure if it's still on the radar) |
I'll take a look in the coming week. Clearly, the old incorrect behavior is something we want to remove as part of the 5.x release. @jeff9finger can you convert the spec to 3.x and see if you still encounter the same issue? Currently, we do advise users to migrate their spec to 3.x to have better support for model composition and inheritance. |
Is there a way to enable inheritance without adding a discriminator field? We rely quite a bit on the "old incorrect behavior" to enable inheritance in code generation so having an alternative (and may it just be an option, disabled by default) to use the old behavior, would be much appreciated. Adding a discriminator field is not always possible unfortunately. |
My company's OAS definitions can not be converted to v3 at this time, as much as I would like to. It is on our roadmap, but not an option at the moment. I'm just trying to get us to use openapi-generator first :-)
As I said above, I am unable to do that at this time. Also, what is the "correct" behavior of composition and inheritance? After more investigation, my example, looks to be an edge case - models with no properties. But IMO, these should be handled properly. So my question is what is the correct behavior? My reading of the OAS v3 spec, states that when a referenced model from Also, when the model containing I have both of these cases in our OAS definitions and we must use v2 at this time. But please link me to the decisions in the inheritance and composition so I can push our management to put a higher priority on moving to v3. Thanks |
There are 2 issues here.
I have added a line in ModelUtils#getParentName() (4.3.x branch) that seems to address this issue, but have not done extensive testing either. Line 1174 in 003165c
Added the following at Line 1192 in 003165c
This allows the desired generation of code from the definitions above. And seems to conform to the OAS v3 as well. But not sure what the current thinking on composition and inheritance is. |
@jeff9finger I've filed #6901 to fix the issue. I tested with the spec you provided and no longer get the models with inheritance. (It turns out the same spec in OAS v3 also has the issue, which is addressed by the PR) |
@m-mohr I don't think that's a good idea. We've been trying hard to correct this since 4.x release. Better update the spec to use discriminator if you want model inheritances. (other tools that can import/read OpenAPI spec also rely on the discriminator field to determine model inheritances) |
@wing328 wee have a similar need than @m-mohr. Our specification is generated from classes in which we don't want to add a discriminator property. Our consumer would like to get inheritance in their generated classes from our spec, for reusability reasons. I wonder in which case one would want to NOT having the inheritance ? |
Don't think you can do that according to the spec
There are definitely use cases in which users simply want the model composition (which is correct according to the spec). You can search in the "issues" to find out those use cases. The current (incorrect) behavior doesn't support multiple inheritances either, which is supported by C++, Perl and more so we think it's a good time to put an end to this incorrect behavior in a major release (5.0.0)
Being the top contributor to Swagger Codegen, I can tell you the behavior is still incorrect according to the spec. Also worth mentioning other tools that support OpenAPI spec won't recognize this kinda hidden convention. Many have made the switch to add discriminators for model inheritances. It's not hard so please give it a try. |
When this issue will be resolved? We can't wait any longer. |
Just a quick note on my company's use/ non-use of discriminator. I don't see a way around this, except maybe some custom templates/vendor extensions that generate the desired behavior. Are there other ideas? I don't want to hijack the topic, in this issue, so please message me privately @jeff9finger or in the slack channel |
i have more less same problem i put and example project into https://github.com/Kenjee/hello-world << simple maven code generation but using same swagger definition with i also was reading https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/ but i stay with "allOf" should be enough, i dont get the need "discriminator"! would be nice to get help and how to integrate the "discriminator" to get simple response object generated in the old way. Why i raise this question: We have a couple of generics in place, so each response is "Response" with 2 fields but some times there is an inhertitad class with more details. UPDATE: solved by simply adding "discriminator" (feels not correct but works) |
There is definitely a use-case for being able to express commonalities across multiple generated types, as per comments on this ticket (and other tickets as well). We have some code that fills / transforms / processes generated data types, and we want to generalize this code in cases where multiple data types share some common structure. I understand there is a some subtlety around "inheritance" and what does it mean for data types. Especially, as it was mentioned above, when you have "multiple" inheritance. I do find "single parent inheritance" (as in this ticket to be quite convenient, but I do agree that it might fail short in more complex scenarios (like multiple I mildly disagree with the suggestion that one can just simply add discriminators and be done with it. In our use-cases, we don't need to express any kind of "inheritance". My main issue with "just add the discriminators" is that it drives long-term, high cost decisions (structure of one's APIs / data types) via minutiae of a particular implementation. Clients of my API should not care that in my service implementation I have switched from version 4.x to 5.x of the generator. Also, rewriting code to introduce a bunch of copy-paste just because new implementation of the generator does not allow us to generalize code in the language of our choice (Java) is also less than ideal. However, I think there is a solution that might work well here: it is possible to extend generator in a way such that it can express commonalities through "interfaces". I created a proof-of-concept in my fork where I add support for
It works well for our case. Actually, for Java generator (but not Spring one) it seems like you can manually do those "traits" via What do you think? |
Any updates for this issue? Currently in version public class Apple extends Fruit {
...
} |
Any news on this? Is it going to be picked up? |
Description
I am not able to get the following definition to generate java or type script correctly.
Have tried with 4.3.1.
In Java, RealCommand is generated as
Notice that I did not specify a discriminator in Command. I expect this definition to generate a composition of
Command
andRealCommand.java
and thatCommand.java
would not be generated.Command.java
file is not generated, but it is also expected as a base class inRealCommand.java
, so this does not compile.There should not be any inheritance here because there is no discriminator.
openapi-generator version
4.3.1
Bug Report Checklist
OpenAPI declaration file content or url
Command line used for generation
openapi-generator generate -i test.yaml -g java --library jersey2 -o java --additional-properties legacyDiscriminatorBehavior=false
Steps to reproduce
Related issues/PRs
#2845
Suggest a fix
I see that maybe
ModelUtils#isFreeFormObject()
should also check to see if the object is used in anallOf
,anyOf
, oroneOf
in any other schema in the definition.But this still does not explain why
RealCommand
is usingCommand
as a base class.The text was updated successfully, but these errors were encountered: