47

I'm using the openApi maven plugin to generate java request/responses for a REST api.

The request has a DateTime property, when I run the generator I get the DateTime property of the attribute represented as java.time.OffsetDateTime. The problem is I have a requirement to represent the property as java.time.Instant.

This is the openApi specification for the request:

"DocumentDto" : {
      "type" : "object",
      "properties" : {
        "uuid" : {
          "type" : "string",
          "format" : "uuid"
        },
        "creationDate" : {
          "type" : "string",
          "format" : "date-time"
        }
      }
    }

The generated java request:

@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2019-05-21T13:07:21.639+02:00[Europe/Zurich]")
public class DocumentDto {
  public static final String SERIALIZED_NAME_UUID = "uuid";
  @SerializedName(SERIALIZED_NAME_UUID)
  private UUID uuid;


  public static final String SERIALIZED_NAME_TEST = "creationDate";
  @SerializedName(SERIALIZED_NAME_TEST)
  private OffsetDateTime creationDate;
}

The maven plugin setup:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>3.3.4</version>
    <executions>
        <execution>
            <id>test-service</id>
            <phase>validate</phase>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>
                    ${project.build.directory}/open-api/swagger.json
                </inputSpec>
                <generatorName>java</generatorName>
                <validateSpec>false</validateSpec>
                <generateApis>false</generateApis>
                <groupId>com.test</groupId>
                <artifactId>test-service</artifactId>
                <modelPackage>test.model</modelPackage>
                <apiPackage>test.api</apiPackage>
                <configOptions>
                    <sourceFolder>src/gen/java/main</sourceFolder>
                    <dateLibrary>java8</dateLibrary>
                    <java8>true</java8>
                </configOptions>
            </configuration>
        </execution>              
    </executions>
</plugin>

I've already tried the typeMappings and importMappings as follow but it had no affect on the generated code:

<typeMappings>DateTime=Instant</typeMappings>
<importMappings>Instant=java.time.Instant</importMappings>
2
  • Did you manage to get this working in the end? I still can't get Instant to work with openApiGenerator and I'm looking for a solution. Commented Jul 27, 2022 at 13:33
  • The following helped me in my case (generator spring 7.5 + gradle): typeMappings.set(["string+date-time": "Instant"]) importMappings.set([Instant: "java.time.Instant"]) Commented May 19, 2024 at 8:23

5 Answers 5

40

I had the same problem but wanted to use LocalDateTime instead of Instant. Adding the following works, at least for entities:

<configuration>
    <typeMappings>
        <typeMapping>OffsetDateTime=LocalDateTime</typeMapping>
    </typeMappings>
    <importMappings>
        <importMapping>java.time.OffsetDateTime=java.time.LocalDateTime</importMapping>
    </importMappings>
</configuration>

i.e. an import for LocalDateTime is added, and any entity fields in the yaml with type format: date-time are mapped to LocalDateTime.

However, for api parameters, no import was added with those settings. After a while I gave up and instead used fully qualified types so that no import is required. Just change the above typeMapping to:

<typeMapping>OffsetDateTime=java.time.LocalDateTime</typeMapping>

Your generated methods afterwards looked like:

default ResponseEntity<List<SomeDto>> someMethodGet(
            @ApiParam(value = "") @Valid @RequestParam(value = "changeDateFrom",
                required = false) @org.springframework.format.annotation.DateTimeFormat(
                    iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME) java.time.LocalDateTime changeDateFrom,
        {
            return getDelegate().someMethodGet(..., changeDateFrom, ...);
        }

PS1 Make sure you use the most recent version of the plugin.

PS2 I used the delegate pattern.

PS3 I used the spring model.

Sign up to request clarification or add additional context in comments.

4 Comments

Just <dateLibrary>java8-localdatetime</dateLibrary> will be enough to make it LocalDateTime (openapi-generator.tech/docs/generators/java). I still can't get it to work with Instant.
@BarbetNL did you have any luck getting it to work with Instant?
No, eventually I gave up, and had to convert it in the java code manually.
For Gradle with Kotlin: typeMappings.set( mapOf( "OffsetDateTime" to "LocalDateTime" ) ) importMappings.set( mapOf( "java.time.OffsetDateTime" to "java.time.LocalDateTime" ) )
35

just add to the configuration of openapi-generator-maven-plugin

<typeMappings>
     <typeMapping>OffsetDateTime=Instant</typeMapping>
</typeMappings>
<importMappings>                                
     <importMapping>java.time.OffsetDateTime=java.time.Instant</importMapping>
</importMappings>

Comments

21

Your changes are overridden by the dateLibrary configuration for the generator. To override date or date-time format types you better disable the dateLibrary by specifying value which is not recognized by the java generators.

Add this to you plugin's <configuration> to achieve this:

  <configOptions>
    <java8>true</java8>
    <dateLibrary>custom</dateLibrary>
  </configOptions>
  <typeMappings>
    <typeMapping>DateTime=Instant</typeMapping>
    <typeMapping>Date=LocalDate</typeMapping>
  </typeMappings>
  <importMappings>
    <importMapping>Instant=java.time.Instant</importMapping>
    <importMapping>LocalDate=java.time.LocalDate</importMapping>
  </importMappings>

You may also want to add <jsr310>true</jsr310> config option, since it is auto enabled when dateLibrary is java8 (but this is used mostly when generating clients as far as I can see).

Comments

13

I know the question was about openapi-generator-maven-plugin, but since looking for the same configuration for org.openapi.generator gradle plugin brought me here, I guess this could be useful for someone else:

The equivalent for org.openapi.generator gradle plugin would be:

openApiGenerate {
    // ...
    typeMappings = [
        OffsetDateTime: "Instant"
    ]
    importMappings = [
        "java.time.OffsetDateTime": "java.time.Instant"
    ]
}

3 Comments

Having a problem with the import not being changed. Any ideas?
Doesn't work for me at all...
Since 5.4.0 of the gradle plugin, the importMappings do not work as one might expect, see: github.com/OpenAPITools/openapi-generator/issues/11506. A workaround would be to remove the importMappings and use OffsetDateTime: "java.time.Instant" in typeMappings.
2

You indeed have to add the mappings as @MaksimYakidovich says, but also change your spec with "format" : "offset-date-time" instead of date-time

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.