openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG] [kotlin-spring] MissingKotlinParameterException instead of BeanValidation exception for missing required property

Open cthiebault opened this issue 5 years ago • 10 comments

Bug Report Checklist

  • [x] Have you provided a full/minimal spec to reproduce the issue?
  • [x] Have you validated the input using an OpenAPI validator (example)?
  • [x] What's the version of OpenAPI Generator used?
  • [x] Have you search for related issues/PRs?
  • [ ] What's the actual output vs expected output?
  • [ ] [Optional] Bounty to sponsor the fix (example)
Description

I defined a required property but instead of getting a bean validation exception, I get a MissingKotlinParameterException:

com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class dto.Component] value failed for JSON property type due to missing (therefore NULL) value for creator parameter type which is a non-nullable type
 at [Source: (PushbackInputStream); line: 1, column: 2] (through reference chain: dto.Component["type"])

Here is the generated DTO:

data class Component (
        @get:NotNull 
        @ApiModelProperty(required = true, value = "")
        @JsonProperty("type") val type: kotlin.String,

        @ApiModelProperty(value = "")
        @JsonProperty("model") val model: kotlin.String? = null
) 

It seems validation is done after the dto is instantiated... and as a required field is null, it can't create a new instance of this dto.

openapi-generator version

kotlin-spring with 4.2.2

OpenAPI declaration file content or url
Component:
  type: object
  required:
    - type
  properties:
    type:
      type: string
    model:
      type: string

cthiebault avatar Jan 27 '20 11:01 cthiebault

👍 Thanks for opening this issue! 🏷 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

auto-labeler[bot] avatar Jan 27 '20 11:01 auto-labeler[bot]

Thanks for the issue!


I've confirmed the steps below reproduces the issue:

issue5121.yaml
openapi: 3.0.2
servers:
  - url: 'http://localhost:8080'
info:
  version: 1.0.0
  title: OpenAPI Petstore
paths:
  /pet:
    post:
      description: test
      operationId: findPets
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Component'
        description: test requestBody
        required: true
      responses:
        '200':
          description: successful operation
          content:
            application/json:
              schema:
                type: string
components:
  schemas:
    Component:
      type: object
      required:
        - type
      properties:
        type:
          type: string
        model:
          type: string
# Generate `kotlin-spring` server
$ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar \
  generate \
  -g kotlin-spring \
  -i issue5121.yaml \
  -o /tmp/issue5121 \
  --additional-properties swaggerAnnotations=true


# Run the generated server
$ cd /tmp/issue5121
$ gradle bootRun


# Send a POST request w/o `type` which is required field.
$ curl -v -X POST "http://localhost:8080/pet" \
    -H "accept: application/json" \
    -H "Content-Type: application/json" \
    -d "{\"model\":\"string\"}" | jq

...
...

{
  "timestamp": "2020-02-05T02:24:59.628+0000",
  "status": 400,
  "error": "Bad Request",
  "message": "JSON parse error: Instantiation of [simple type, class org.openapitools.model.Component] value failed for JSON property type due to missing (therefore NULL) value for creator parameter type which is a non-nullable type; nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class org.openapitools.model.Component] value failed for JSON property type due to missing (therefore NULL) value for creator parameter type which is a non-nullable type\n at [Source: (PushbackInputStream); line: 1, column: 18] (through reference chain: org.openapitools.model.Component[\"type\"])",
  "path": "/pet"
}

ackintosh avatar Feb 05 '20 02:02 ackintosh

If declear nullable and embed @field:Notnull :

data class Component(

    @field:NotNull
    @ApiModelProperty(example = "null", required = true, value = "")
    @JsonProperty("type") val type: kotlin.String?,

    @ApiModelProperty(example = "null", value = "")
    @JsonProperty("model") val model: kotlin.String? = null
)

This issue will be solved. What do you think about this solution? @ackintosh @cthiebault

yutaka0m avatar Feb 06 '20 05:02 yutaka0m

It would work... but it's too bad to have a poor model with non null field becoming nullable because of validation :( Maybe related to https://stackoverflow.com/a/41994512/386713 ?

cthiebault avatar Feb 06 '20 13:02 cthiebault

Hmm... I can't think of other way. 🤔 💦

Technical Committee (Kotlin): @jimschubert @dr4ke616 @karismann @Zomzog @andrewemery @4brunu

Do you have any ideas?

ackintosh avatar Feb 07 '20 03:02 ackintosh

Seems like a secondary constructor with and JsonCreator might work best, maybe also Delegates.notNull.

I'm not sure when I'd have time to look into, though.

jimschubert avatar Feb 07 '20 04:02 jimschubert

I think you can set empty string as default value. Jackson should be able to parse it successfully.

@field:NotNull
    @ApiModelProperty(example = "null", required = true, value = "")
    @JsonProperty("type") val type: kotlin.String = '',

kodai-shirafuta-skl avatar Feb 24 '22 06:02 kodai-shirafuta-skl

Guys please pay attention to this one, it messes up the validation flow and makes us devs do weird things to make it work.

zipper2110 avatar Feb 12 '24 11:02 zipper2110

@zipper2110 may I know if you can contribute a PR to start with?

wing328 avatar Feb 12 '24 18:02 wing328

quite an old story, any update on this?

aldex32 avatar May 07 '24 11:05 aldex32