33

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>
sromdhane
  • 375
  • 1
  • 4
  • 7
  • 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. – BarbetNL Jul 27 '22 at 13:33

5 Answers5

29

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>
28

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.

PS2 I used the spring model.

zmeeagain
  • 439
  • 4
  • 4
  • 2
    Just `java8-localdatetime` will be enough to make it LocalDateTime (https://openapi-generator.tech/docs/generators/java/). I still can't get it to work with Instant. – BarbetNL Jul 27 '22 at 13:32
  • @BarbetNL did you have any luck getting it to work with Instant? – Dani Jun 23 '23 at 20:42
14

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).

tsachev
  • 1,111
  • 10
  • 14
9

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"
    ]
}
Daniel Plucenio
  • 111
  • 2
  • 5
  • Having a problem with the import not being changed. Any ideas? – Martin Mansour Apr 07 '22 at 11:37
  • Doesn't work for me at all... – Demigod Apr 05 '23 at 13:03
  • Since 5.4.0 of the gradle plugin, the importMappings do not work as one might expect, see: https://github.com/OpenAPITools/openapi-generator/issues/11506. A workaround would be to remove the importMappings and use `OffsetDateTime: "java.time.Instant"` in typeMappings. – Semaphor Jun 14 '23 at 06:34
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

petronius
  • 451
  • 3
  • 11