Skip to content

Commit 7ade6f2

Browse files
authored
[Java] fix: map the OAS 3.1 null type to Object, not a never-generated ModelNull (#24935)
AbstractJavaCodegen has no "null" entry in typeMapping, so getSchemaType falls through to toModelName("null"). "null" is a Java reserved word, so the model name becomes ModelNull, a class the generator never emits, and the generated client does not compile. Python, Go, Elixir and Xojo already map "null" in their typeMapping; this adds the Java one. The 3_1 java fixture gains third_property with the quoted form of the null type. The existing second_property uses unquoted "type: null", which YAML reads as a null scalar, so that property carries no type at all and already generated Object. Only bin/configs/java-okhttp-gson-3.1.yaml consumes this fixture, and samples-java-petsore-client-jdk11 builds that sample, so the regression is now covered in CI.
1 parent 5a0fa87 commit 7ade6f2

6 files changed

Lines changed: 45 additions & 3 deletions

File tree

‎modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ public AbstractJavaCodegen() {
304304
typeMapping.put("date", "Date");
305305
typeMapping.put("file", "File");
306306
typeMapping.put("AnyType", "Object");
307+
typeMapping.put("null", "Object");
307308
typeMapping.put("enum", "Enum");
308309

309310
importMapping.put("BigDecimal", "java.math.BigDecimal");

‎modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,4 +1114,13 @@ public void removeAnnotationsTest() {
11141114
public void testSanitizedDataType() {
11151115
assertThat(codegen.sanitizeDataType("org.somepkg.DataType")).isEqualTo("orgsomepkgDataType");
11161116
}
1117+
1118+
@Test(description = "the OAS 3.1 null type maps to Object instead of a never-generated ModelNull (issue 24520)")
1119+
public void testNullTypeMapsToObject() {
1120+
Schema<?> nullSchema = new Schema<>().type("null");
1121+
1122+
assertThat(codegen.getSchemaType(nullSchema)).isEqualTo("Object");
1123+
assertThat(codegen.getTypeDeclaration(nullSchema)).isEqualTo("Object");
1124+
assertThat(codegen.getTypeDeclaration(new ArraySchema().items(nullSchema))).isEqualTo("List<Object>");
1125+
}
11171126
}

‎modules/openapi-generator/src/test/resources/3_1/java/petstore.yaml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,3 +1135,6 @@ components:
11351135
second_property:
11361136
description: just null type
11371137
type: null
1138+
third_property:
1139+
description: null type declared as the OAS 3.1 quoted string
1140+
type: 'null'

‎samples/client/petstore/java/okhttp-gson-3.1/api/openapi.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,8 @@ components:
12151215
$ref: "#/components/schemas/Pet"
12161216
second_property:
12171217
description: just null type
1218+
third_property:
1219+
description: null type declared as the OAS 3.1 quoted string
12181220
updatePetWithForm_request:
12191221
properties:
12201222
name:

‎samples/client/petstore/java/okhttp-gson-3.1/docs/PetWithTypesObjectNullAndRef.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
|------------ | ------------- | ------------- | -------------|
1010
|**firstProperty** | [**Pet**](Pet.md) | | [optional] |
1111
|**secondProperty** | **Object** | just null type | [optional] |
12+
|**thirdProperty** | **Object** | null type declared as the OAS 3.1 quoted string | [optional] |
1213

1314

1415

‎samples/client/petstore/java/okhttp-gson-3.1/src/main/java/org/openapitools/client/model/PetWithTypesObjectNullAndRef.java‎

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ public class PetWithTypesObjectNullAndRef {
6363
@javax.annotation.Nullable
6464
private Object secondProperty = null;
6565

66+
public static final String SERIALIZED_NAME_THIRD_PROPERTY = "third_property";
67+
@SerializedName(SERIALIZED_NAME_THIRD_PROPERTY)
68+
@javax.annotation.Nullable
69+
private Object thirdProperty = null;
70+
6671
public PetWithTypesObjectNullAndRef() {
6772
}
6873

@@ -103,6 +108,25 @@ public void setSecondProperty(@javax.annotation.Nullable Object secondProperty)
103108
this.secondProperty = secondProperty;
104109
}
105110

111+
112+
public PetWithTypesObjectNullAndRef thirdProperty(@javax.annotation.Nullable Object thirdProperty) {
113+
this.thirdProperty = thirdProperty;
114+
return this;
115+
}
116+
117+
/**
118+
* null type declared as the OAS 3.1 quoted string
119+
* @return thirdProperty
120+
*/
121+
@javax.annotation.Nullable
122+
public Object getThirdProperty() {
123+
return thirdProperty;
124+
}
125+
126+
public void setThirdProperty(@javax.annotation.Nullable Object thirdProperty) {
127+
this.thirdProperty = thirdProperty;
128+
}
129+
106130
/**
107131
* A container for additional, undeclared properties.
108132
* This is a holder for any undeclared properties as specified with
@@ -159,7 +183,8 @@ public boolean equals(Object o) {
159183
}
160184
PetWithTypesObjectNullAndRef petWithTypesObjectNullAndRef = (PetWithTypesObjectNullAndRef) o;
161185
return Objects.equals(this.firstProperty, petWithTypesObjectNullAndRef.firstProperty) &&
162-
Objects.equals(this.secondProperty, petWithTypesObjectNullAndRef.secondProperty)&&
186+
Objects.equals(this.secondProperty, petWithTypesObjectNullAndRef.secondProperty) &&
187+
Objects.equals(this.thirdProperty, petWithTypesObjectNullAndRef.thirdProperty)&&
163188
Objects.equals(this.additionalProperties, petWithTypesObjectNullAndRef.additionalProperties);
164189
}
165190

@@ -169,7 +194,7 @@ private static <T> boolean equalsNullable(JsonNullable<T> a, JsonNullable<T> b)
169194

170195
@Override
171196
public int hashCode() {
172-
return Objects.hash(firstProperty, secondProperty, additionalProperties);
197+
return Objects.hash(firstProperty, secondProperty, thirdProperty, additionalProperties);
173198
}
174199

175200
private static <T> int hashCodeNullable(JsonNullable<T> a) {
@@ -185,6 +210,7 @@ public String toString() {
185210
sb.append("class PetWithTypesObjectNullAndRef {\n");
186211
sb.append(" firstProperty: ").append(toIndentedString(firstProperty)).append("\n");
187212
sb.append(" secondProperty: ").append(toIndentedString(secondProperty)).append("\n");
213+
sb.append(" thirdProperty: ").append(toIndentedString(thirdProperty)).append("\n");
188214
sb.append(" additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n");
189215
sb.append("}");
190216
return sb.toString();
@@ -204,7 +230,7 @@ private String toIndentedString(Object o) {
204230

205231
static {
206232
// a set of all properties/fields (JSON key names)
207-
openapiFields = new HashSet<String>(Arrays.asList("first_property", "second_property"));
233+
openapiFields = new HashSet<String>(Arrays.asList("first_property", "second_property", "third_property"));
208234

209235
// a set of required properties/fields (JSON key names)
210236
openapiRequiredFields = new HashSet<String>(0);

0 commit comments

Comments
 (0)