Skip to content

Getters returning NULL when model extends HashMap #1112

Open
@tmulle

Description

@tmulle

Tell us the extension you're using

Client

I tried this:

We are using quarkus-resteasy-problem for our REST error responses and their HttpProblem class extends RuntimeException.

When the client openapi generator creates the model for that schema it generates the code but ALL of the getters return NULL which the actual values are really stored in the parent MAP.

Here is the code generated for the HttpProblem.

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonTypeName;
import com.fasterxml.jackson.annotation.JsonValue;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
  * HTTP Problem Response according to RFC9457 & RFC7807
 **/
@com.fasterxml.jackson.annotation.JsonIgnoreProperties(ignoreUnknown = true)
public class HttpProblem extends HashMap<String, Object> {

    /**
      * A optional URI reference that identifies the problem type
     **/
    private URI type;
    /**
      * A optional, short, human-readable summary of the problem type
     **/
    private String title;
    /**
      * The HTTP status code for this occurrence of the problem
     **/
    private Integer status;
    /**
      * A optional human-readable explanation specific to this occurrence of the problem
     **/
    private String detail;
    /**
      * A URI reference that identifies the specific occurrence of the problem
     **/
    private URI instance;

    /**
    * A optional URI reference that identifies the problem type
    * @return type
    **/
    @JsonProperty("type")
    @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
    public URI getType() {
        return type;
    }

    /**
     * Set type
     **/
    public void setType(URI type) {
        this.type = type;
    }

    public HttpProblem type(URI type) {
        this.type = type;
        return this;
    }

    /**
    * A optional, short, human-readable summary of the problem type
    * @return title
    **/
    @JsonProperty("title")
    @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
    public String getTitle() {
        return title;
    }

    /**
     * Set title
     **/
    public void setTitle(String title) {
        this.title = title;
    }

    public HttpProblem title(String title) {
        this.title = title;
        return this;
    }

    /**
    * The HTTP status code for this occurrence of the problem
    * @return status
    **/
    @JsonProperty("status")
    @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
    public Integer getStatus() {
        return status;
    }

    /**
     * Set status
     **/
    public void setStatus(Integer status) {
        this.status = status;
    }

    public HttpProblem status(Integer status) {
        this.status = status;
        return this;
    }

    /**
    * A optional human-readable explanation specific to this occurrence of the problem
    * @return detail
    **/
    @JsonProperty("detail")
    @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
    public String getDetail() {
        return detail;
    }

    /**
     * Set detail
     **/
    public void setDetail(String detail) {
        this.detail = detail;
    }

    public HttpProblem detail(String detail) {
        this.detail = detail;
        return this;
    }

    /**
    * A URI reference that identifies the specific occurrence of the problem
    * @return instance
    **/
    @JsonProperty("instance")
    @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
    public URI getInstance() {
        return instance;
    }

    /**
     * Set instance
     **/
    public void setInstance(URI instance) {
        this.instance = instance;
    }

    public HttpProblem instance(URI instance) {
        this.instance = instance;
        return this;
    }

    /**
     * Create a string representation of this pojo.
     **/
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("class HttpProblem {\n");
        sb.append("    ").append(toIndentedString(super.toString())).append("\n");
        sb.append("    type: ").append(toIndentedString(type)).append("\n");
        sb.append("    title: ").append(toIndentedString(title)).append("\n");
        sb.append("    status: ").append(toIndentedString(status)).append("\n");
        sb.append("    detail: ").append(toIndentedString(detail)).append("\n");
        sb.append("    instance: ").append(toIndentedString(instance)).append("\n");
        
        sb.append("}");
        return sb.toString();
    }

    /**
     * Compares this object to the specified object. The result is
     * {@code true} if and only if the argument is not
     * {@code null} and is a {@code HttpProblem} object that
     * contains the same values as this object.
     *
     * @param   obj   the object to compare with.
     * @return  {@code true} if the objects are the same;
     *          {@code false} otherwise.
     **/
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;

        HttpProblem model = (HttpProblem) obj;

        return java.util.Objects.equals(type, model.type) &&
        java.util.Objects.equals(title, model.title) &&
        java.util.Objects.equals(status, model.status) &&
        java.util.Objects.equals(detail, model.detail) &&
        java.util.Objects.equals(instance, model.instance);
    }

    /**
     * Returns a hash code for a {@code HttpProblem}.
     *
     * @return a hash code value for a {@code HttpProblem}.
     **/
    @Override
    public int hashCode() {
        return java.util.Objects.hash(type,
        title,
        status,
        detail,
        instance);
    }

    /**
     * Convert the given object to string with each line indented by 4 spaces
     * (except the first line).
     */
    private static String toIndentedString(Object o) {
        if (o == null) {
            return "null";
        }
        return o.toString().replace("\n", "\n    ");
    }

    /**
      * HTTP Problem Response according to RFC9457 & RFC7807
     **/
    @com.fasterxml.jackson.annotation.JsonIgnoreProperties(ignoreUnknown = true)
    public static class HttpProblemQueryParam extends HashMap<String, Object> {

        /**
          * HTTP Problem Response according to RFC9457 & RFC7807
         **/
        @jakarta.ws.rs.QueryParam("type")
        private URI type;
        /**
          * HTTP Problem Response according to RFC9457 & RFC7807
         **/
        @jakarta.ws.rs.QueryParam("title")
        private String title;
        /**
          * HTTP Problem Response according to RFC9457 & RFC7807
         **/
        @jakarta.ws.rs.QueryParam("status")
        private Integer status;
        /**
          * HTTP Problem Response according to RFC9457 & RFC7807
         **/
        @jakarta.ws.rs.QueryParam("detail")
        private String detail;
        /**
          * HTTP Problem Response according to RFC9457 & RFC7807
         **/
        @jakarta.ws.rs.QueryParam("instance")
        private URI instance;

        /**
        * A optional URI reference that identifies the problem type
        * @return type
        **/
        @com.fasterxml.jackson.annotation.JsonProperty("type")
        public URI getType() {
            return type;
        }

        /**
         * Set type
         **/
        public void setType(URI type) {
            this.type = type;
        }

        public HttpProblemQueryParam type(URI type) {
            this.type = type;
            return this;
        }

        /**
        * A optional, short, human-readable summary of the problem type
        * @return title
        **/
        @com.fasterxml.jackson.annotation.JsonProperty("title")
        public String getTitle() {
            return title;
        }

        /**
         * Set title
         **/
        public void setTitle(String title) {
            this.title = title;
        }

        public HttpProblemQueryParam title(String title) {
            this.title = title;
            return this;
        }

        /**
        * The HTTP status code for this occurrence of the problem
        * @return status
        **/
        @com.fasterxml.jackson.annotation.JsonProperty("status")
        public Integer getStatus() {
            return status;
        }

        /**
         * Set status
         **/
        public void setStatus(Integer status) {
            this.status = status;
        }

        public HttpProblemQueryParam status(Integer status) {
            this.status = status;
            return this;
        }

        /**
        * A optional human-readable explanation specific to this occurrence of the problem
        * @return detail
        **/
        @com.fasterxml.jackson.annotation.JsonProperty("detail")
        public String getDetail() {
            return detail;
        }

        /**
         * Set detail
         **/
        public void setDetail(String detail) {
            this.detail = detail;
        }

        public HttpProblemQueryParam detail(String detail) {
            this.detail = detail;
            return this;
        }

        /**
        * A URI reference that identifies the specific occurrence of the problem
        * @return instance
        **/
        @com.fasterxml.jackson.annotation.JsonProperty("instance")
        public URI getInstance() {
            return instance;
        }

        /**
         * Set instance
         **/
        public void setInstance(URI instance) {
            this.instance = instance;
        }

        public HttpProblemQueryParam instance(URI instance) {
            this.instance = instance;
            return this;
        }

        /**
         * Create a string representation of this pojo.
         **/
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("class HttpProblemQueryParam {\n");
            sb.append("    ").append(toIndentedString(super.toString())).append("\n");
            sb.append("    type: ").append(toIndentedString(type)).append("\n");
            sb.append("    title: ").append(toIndentedString(title)).append("\n");
            sb.append("    status: ").append(toIndentedString(status)).append("\n");
            sb.append("    detail: ").append(toIndentedString(detail)).append("\n");
            sb.append("    instance: ").append(toIndentedString(instance)).append("\n");
            sb.append("}");
            return sb.toString();
        }

        /**
         * Convert the given object to string with each line indented by 4 spaces
         * (except the first line).
         */
        private static String toIndentedString(Object o) {
            if (o == null) {
                return "null";
            }
            return o.toString().replace("\n", "\n    ");
        }
    }}

When I print out the model returned from the Rest call I can see the values from the parent but not in the child class.

class HttpProblem {
    {instance=/api/v1/bcp/notifications/client/436c5f5f-414c-4b12-ab10-47219da0a8f8, X-Request-Id=6ac32b58-47a2-45ee-9691-16841b216fd5, detail=Client 436c5f5f-414c-4b12-ab10-47219da0a8f8 does not exist, title=Not Found, status=404}
    type: null
    title: null
    status: null
    detail: null
    instance: null
}```

Here is the SCHEMA snippet for the HTTPProblem that gets auto generated from Quarkus OpenAPI extension:

```json
"HttpProblem" : {
        "description" : "HTTP Problem Response according to RFC9457 & RFC7807",
        "additionalProperties" : true,
        "type" : "object",
        "properties" : {
          "type" : {
            "type" : "string",
            "format" : "uri",
            "description" : "A optional URI reference that identifies the problem type",
            "examples" : [ "https://example.com/errors/not-found" ]
          },
          "title" : {
            "type" : "string",
            "description" : "A optional, short, human-readable summary of the problem type",
            "examples" : [ "Not Found" ]
          },
          "status" : {
            "type" : "integer",
            "format" : "int32",
            "description" : "The HTTP status code for this occurrence of the problem",
            "examples" : [ 404 ]
          },
          "detail" : {
            "type" : "string",
            "description" : "A optional human-readable explanation specific to this occurrence of the problem",
            "examples" : [ "Record not found" ]
          },
          "instance" : {
            "type" : "string",
            "format" : "uri",
            "description" : "A URI reference that identifies the specific occurrence of the problem",
            "examples" : [ "https://api.example.com/errors/123" ]
          }
        }
      },
      ...

This happened:

Calling any of the getters generated always returns NULL

I expected this:

I should get the values returned when I call the getters like getStatus() and getDetails(), etc. and not NULL

Is there a workaround?

No response

How can we try to reproduce the issue?

No response

Anything else?

No response

Output of uname -a or ver

No response

Output of java -version

No response

Quarkus OpenApi version or git rev

No response

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

No response

Community Notes

  • Please vote by adding a 👍 reaction to the issue to help us prioritize.
  • If you are interested to work on this issue, please leave a comment.name: Bug Report 🐞

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:clientThis item is related to the client extension

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions