Skip to content

[BUG][Java][client] Erroneous support for nullable attributes #3435

@bkabrda

Description

@bkabrda

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
    • The included modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml can be used to reproduce this.
  • Have you validated the input using an OpenAPI validator (example)?
  • What's the version of OpenAPI Generator used?
    • All versions seem to be affected (I used 4.0.2)
  • Have you search for related issues/PRs?
    • The same behaviour applied to Go, reported at [1] and fixed in go-experimental in [2].
  • What's the actual output vs expected output?
    • The problem is that for attributes marked as nullable, null is never sent.
  • [Optional] Bounty to sponsor the fix (example)
Description

The problem is very similar to what was described in [1] - if an attribute is marked as nullable in the OpenAPI spec, it's not actually possible to send a null value in a POST/PUT request for it (using okhttp/gson client, but AFAICS other clients would have these issues as well).

openapi-generator version

4.0.2, but the issue seems to always have been there.

OpenAPI declaration file content or url

modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml

Command line used for generation

openapi-generator -g java -i modules/openapi-generator/src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing.yaml -o /tmp/petstore/

Steps to reproduce

You just need to generate a Java client for OpenAPI spec that has any nullable attributes and see that it doesn't really send nulls for them in the request JSON objects.

Related issues/PRs

[1] #522
[2] #3371

Suggest a fix

My solution for Go from [2], which I believe is correct, considers 4 different states for every attribute:

  1. not required, not nullable
  2. required, not nullable
  3. not required, nullable
  4. required, nullable

All these 4 states need to be covered properly in order to be able to send the requests correctly according to the spec. Here's my thinking on how the 4 above scenarios should behave:

  1. no change required, this already works (if attribute is null, then it's not serialized at all)
  2. no change required, this already works (attribute can't be null, a non-null value is always sent)
  3. (change) there has to be a flag for the attribute, which would carry the information whether or not a null value is explicit or not; if this flag is true and the attribute is null, it would get serialized as null; if this flag is false and the attribute is null, it wouldn't get serialized at all
  4. (change) the attribute is serialized as null if it has null value

I propose that an {{name}}isExplicitNull attribute is added to the POJO class for every nullable attribute (defaultin to false as well as set{{name}}IsExplicitNull and is{{name}}ExplicitNull setter/getter. In addition to that, we'd need to add custom serialization logic that would respect these "explicit null flags" to properly serialize the request.

I'm also fairly certain that this can be done as a backwards compatible change, since it will only be adding things, not removing or changing the current API of the generated classes.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions