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

JsonParser#getString() is valid only for KEY_NAME, VALUE_STRING, VALUE_NUMBER parser states. But current parser state is VALUE_NULL

Open KUPRAM-PRAMOD opened this issue 10 months ago • 3 comments

Bug Report Checklist

The custom Deserializer method not able to handle null value for enum and throwing below exception

JsonParser#getString() is valid only for KEY_NAME, VALUE_STRING, VALUE_NUMBER parser states. But current parser state is VALUE_NULL

Using Open openapi-generator-maven-plugin v7.11.0 with below configuration:

    <plugin>
            <groupId>org.openapitools</groupId>
            <artifactId>openapi-generator-maven-plugin</artifactId>
            <version>7.11.0.0</version>
            <configuration>
                <addCompileSourceRoot>true</addCompileSourceRoot>
                <configOptions>
                    <useJakartaEe>true</useJakartaEe>
                    <microprofileRestClientVersion>3.0</microprofileRestClientVersion>
                    <modelNullable>true</modelNullable>
                    <prependFormOrBodyParameters>true</prependFormOrBodyParameters>
                    <serializableModel>false</serializableModel>
                    <dateLibrary>java8</dateLibrary>
                    <java17>true</java17>
                    <useOptionalForEnumFromValue>true</useOptionalForEnumFromValue>
                    <openApiNullable>false</openApiNullable>
                </configOptions>
            </configuration>
          

Below is the enum definiton in openapi.yaml .

    division:
      type: string
      enum:
        - PC
      example: PC

and its generate enum class as below

@JsonbTypeSerializer(DivisionEnum.Serializer.class) @JsonbTypeDeserializer(DivisionEnum.Deserializer.class) public enum DivisionEnum {

PC(String.valueOf("pc"));


String value;

DivisionEnum (String v) {
    value = v;
}

public String value() {
    return value;
}

@Override
public String toString() {
    return String.valueOf(value);
}

public static Optional<DivisionEnum> fromValue(String v) {
    for (DivisionEnum b : DivisionEnum.values()) {
        if (String.valueOf(b.value).equals(v)) {
            return Optional.of(b);
        }
    }
    return Optional.empty();
}

public static final class Deserializer implements JsonbDeserializer<DivisionEnum> {
    @Override
    public DivisionEnum deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
        for (DivisionEnum b : DivisionEnum.values()) {
            if (String.valueOf(b.value).equals(parser.getString())) {
                return b;
            }
        }
        throw new IllegalArgumentException("Unexpected value '" + parser.getString() + "'");
    }
}

public static final class Serializer implements JsonbSerializer<DivisionEnum> {
    @Override
    public void serialize(DivisionEnum obj, JsonGenerator generator, SerializationContext ctx) {
        generator.write(obj.value);
    }
}

parser.getString() throwing below error when enum value is null.

JsonParser#getString() is valid only for KEY_NAME, VALUE_STRING, VALUE_NUMBER parser states. But current parser state is VALUE_NULL

Note: Using jakarta 10 and java 17

KUPRAM-PRAMOD avatar Apr 02 '25 12:04 KUPRAM-PRAMOD

We have the same problem.

We have a nullable enum as part of our API, and before upgrading from 7.2.0 to 7.13.0 this was fine.

peacememories avatar May 13 '25 14:05 peacememories

We have the same issue too. Is there a workaround available maybe?

edgarvonk avatar May 30 '25 15:05 edgarvonk

We found a workaround (not pretty, but it works for us) by overriding the default OpenAPI Generator enumOuterClass.mustache template and by changing the following bit of code:

public static final class Deserializer implements JsonbDeserializer<{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}}> {
    @Override
    public {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
      // manual change to handle null values correctly.
      try {
        return fromValue(parser.getString());
      } catch (IllegalStateException exception) {
        // If the parser is at a null value, we return null instead of throwing an exception.
        // This is a workaround for: https://github.com/OpenAPITools/openapi-generator/issues/21015
        return null;
      }
    }
  }

To override these Mustache templates we specify the following in our Gradle build file for our OpenAPI Generator task:

templateDir.set("$rootDir/src/main/resources/openapi-generator-templates")

edgarvonk avatar May 30 '25 17:05 edgarvonk