openapi-generator: [BUG] [JAVA] openapi-generator-maven-plugin does not handle allOf composed of multiple objects

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

Using allOf composed of multiple objects in a response does not generate a class combining these multiple objects. Instead it uses the first class defined in the allOf section.

openapi-generator version

Version 5.2.0:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>5.2.0</version>
</plugin>

I have also tested with master (5.2.1-SNAPSHOT), commit fe9636e9.

OpenAPI declaration file content or url

Important part here is the allOf:

openapi: 3.0.0
info:
  title: Test
  version: v1
paths:
  /test:
    get:
      operationId: get
      responses:
        '200':
          description: Get
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/A'
                  - $ref: '#/components/schemas/B'
components:
  schemas:
    A:
      type: object
      properties:
        attA:
          type: string
    B:
      type: object
      properties:
        attB:
          type: integer
Generation Details
generatorName: java
inputSpec: openapi.yaml
Steps to reproduce
 mvn org.openapitools:openapi-generator-maven-plugin:5.2.0:generate \
    -Dopenapi.generator.maven.plugin.inputSpec=openapi.yaml \
    -Dopenapi.generator.maven.plugin.generatorName=java

Shows a warning:

[WARNING] allOf with multiple schemas defined. Using only the first one: A

It generates classes A and B. But when calling get(), the value returned by the call is A:

DefaultApi api = new DefaultApi();
A a = api.get();

I expected instead a composite object with A and B properties (attA and attB), like this (result from https://editor.swagger.io/):

image

Related issues/PRs
Suggest a fix

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 48
  • Comments: 55 (11 by maintainers)

Most upvoted comments

@paulbors of course editing the spec is possible (and that’s the solution we used now), but this is not very convenient if the openapi evolves : we have to manually change our version to match the new version.

Besides, as you said editing the openapi is just a workaround.

That’s why I opened this issue : the fact that the generator does not generate right classes when providing a valid openapi spec (as in my example) is probably a bug and as so probably needs to be fixed.

I was referring to your comments here: https://stackoverflow.com/questions/68773761/openapi-generator-maven-plugin-java-does-not-handle-allof-properly

Right, so we know is not working with:

  • More than one $ref
  • A combination of $ref and inline schema

We know it works with:

  • A single $ref
  • A full inline schema

So that’s the real bug here. Now let’s see which one of us (you or me) needs this to work first and puts out a Pull Request to this repo fixing it.

The beauty of open source code… 😃

Thanks @wing328 for your efforts. Great project by the way!

I have sent a small bounty of 50$

Can this please be fixed!!

For me a “A single $ref” also doesnt work when using allOf 😦

However my case is a bit different:

Customer:
  allOf:
    - $ref: '#/components/schemas/CreateCustomer'
  required:
    - customerId
  properties:
    customerId:
      type: string

I get a java class that only has “customerId” field

Upgrading from swagger v2 to swagger v3 we hit exactly this issue when generating java code.

In swagger v2 codegen, allOf types would nicely be composed.

In swagger v3 only the first type in the allOf would become part of the model…

As the OpenAPITool community seems more active I now upgraded to OpenAPITools codegen.

Although it still logs a nonsense warning about multiple types in allOf (please merge https://github.com/OpenAPITools/openapi-generator/pull/7446 or other PR removing this warning in the correct way!):

[main] WARN o.o.codegen.DefaultCodegen - allOf with multiple schemas defined. Using only the first one: XYZ [main] WARN o.o.codegen.DefaultCodegen - More than one inline schema specified in allOf:. Only the first one is recognized. All others are ignored.

as a matter of fact the generator 5.4.0 does correctly generate the complete composed java model!

PR merged. Please give it a try with the latest master via SNAPSHOT jar, docker images or build the project locally.

Also in case of <generatorName>spring</generatorName> there is the same warning and only the first ref is used in the generation of the model. Tested with plugin version 5.4.0 and 6.0.0-beta

@fbett thanks for the sponsorship 👍

@derkd I’ve filed https://github.com/OpenAPITools/openapi-generator/pull/15039 to add a new openapi-generator normalizer rule to handle properties and allOf in the same level.

Tested with your spec and the output compiles without issue.

     getUserCallLogsResponse200:
       allOf:
       - $ref: '#/components/schemas/baseResponse'
-      example:
-        additional_data:
-          start: 0
-          limit: 6
-          more_items_in_collection: true
-        data:
-        - null
-        - null
-      properties:
-        data:
-          items:
-            $ref: '#/components/schemas/responseCallLogObject'
-          type: array
-        additional_data:
-          $ref: '#/components/schemas/fieldsResponse200_allOf_additional_data'
+      - $ref: '#/components/schemas/getUserCallLogsResponse200_allOf'
       title: getUserCallLogsResponse200

Command:

java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i https://developers.pipedrive.com/docs/api/v1/openapi.yaml -o /tmp/allofbugfix3/ --openapi-normalizer REFACTOR_ALLOF_WITH_PROPERTIES_ONLY=true,SIMPLIFY_BOOLEAN_ENUM=true

@consultantleon @nikosmoum @skwasniak I am not sure how you got a complete composite object. I’ve tried with the example in my first post, using the latest versions at the time of the plugin (5.4.0 and 6.0.0-beta) and the latest supported openapi spec (3.0.3), and I still got the same result. Maybe you have a different case than the example in my first post.

In my case, the Java DefaultApi class generated looks like this:

public class DefaultApi {
    // ...

    public A get() throws ApiException {
        ApiResponse<A> localVarResp = getWithHttpInfo();
        return localVarResp.getData();
    }

    // ...
}

The get() method does not return a composite object of A and B, but just A.

Also, I’ve tried with Kotlin:

 mvn org.openapitools:openapi-generator-maven-plugin:5.4.0:generate \
    -Dopenapi.generator.maven.plugin.inputSpec=openapi.yaml \
    -Dopenapi.generator.maven.plugin.generatorName=kotlin

And got the same result (the method get() only return A:

class DefaultApi(basePath: kotlin.String = defaultBasePath) : ApiClient(basePath) {
    // ...

    fun get() : A {
        val localVarResponse = getWithHttpInfo()

        return when (localVarResponse.responseType) {
            // ...
        }
    }

    // ...
}

As @fastluca and others said, the bug is still present.

By the way, these 3 OpenAPI specs parts (replace in my initial openapi.yaml):

schema:
  allOf:
    - $ref: '#/components/schemas/A'
  properties:
    b:
      type: integer

and:

schema:
  allOf:
    - $ref: '#/components/schemas/A'
    - type: object
      properties:
        b:
          type: integer

and:

schema:
  allOf:
    - $ref: '#/components/schemas/A'
  type: "object"
  properties:
    b:
      type: integer

give exactly the same result in Java and Kotlin (get() method always returns A, and the b field does not appear anywhere).

+1 same issue

Also experencing this issue with the C# dotnet Core generator.

Any update on this? I am using 6.2.0 and still getting this warning and compilation errors in models generated.

Any update? This is still a blocker in 6.1.0

Using 5.4.0 with Java and agree with @consultantleon. The generated model is composed correctly from all schemas defined under the allOf, but this warning message is clearly wrong (allOf is supposed to be used with multiple schemas).

@koalo I’m not saying this is accordingly to open api spec, I’m just stating a workaround that works for kotlin and kotlin-spring generators. But you have the point, my wording “Where the correct is:” is misleading.

Anyhow it is a bug that needs attention, as probably it is widely used feature.

P.S. My API spec is swagger: "2.0".

@skwasniak I am not sure if your second option is really correct. On https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/ you can find the following example:

       allOf: # Combines the main `Pet` schema with `Cat`-specific properties 
        - $ref: '#/components/schemas/Pet'
        - type: object
          # all other properties specific to a `Cat`
          properties:
            hunts:
              type: boolean
            age:
              type: integer

What am I getting wrong here?

The warning is gone butt still it does not work (using java)