Skip to main content
Rate this page

Generate a Typed OData Client With the OData Generator

The OData Generator allows for generating Java classes from the metadata of an OData service. These classes which are referred to as typed OData client provide type-safe access to the service.

In general, there are three ways to use the generator:

  • Via the dedicated maven plugin
  • Via the command-line interface (CLI)
  • By instantiating and invoking it at runtime

The maven plugin is usually the recommended way as it integrates nicely with most project setups and makes configuration easy. However, the other two approaches are available and all are documented below.

For all three the required input is an EDMX file holding the service metadata.

note

Please be aware that OData v2 and OData v4 service definitions are not interchangeable. There is a dedicated generator for each protocol version and it only accepts service definitions for that version.

tip

The OData VDM generator does support all data types per the OData specification. If your OData service metadata uses a data type not listed in the standard, please alter your metadata to use a compatible data type from the specification instead.

For example, a non-standard Edm.Float type can be substituted by Edm.Single type from the OData specification.

Using the OData Generator​

Regardless of how the generator is invoked the generated code requires some dependencies to be present. Therefore, it is required to ensure the following dependencies are present in your project:

<dependency>
<groupId>com.sap.cloud.sdk.datamodel</groupId>
<artifactId>odata-v4-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<scope>provided</scope>
</dependency>
Lombok and Dependency injection are mandatory!

Lombok and dependency injections are used by the generated typed OData client classes, that is why they are needed but only with the scope provided. Furthermore, some common IDEs (e.g. IntelliJ, Eclipse) require plugins to recognize these annotations. See the note on missing accessors

Using the OData Generator Maven Plugin​

The maven plugin is most useful if you would like to use the generated code within a maven project. Use it by adding it to your application/pom.xml file under the <plugin> section:

<plugin>
<groupId>com.sap.cloud.sdk.datamodel</groupId>
<artifactId>odata-v4-generator-maven-plugin</artifactId>
<!-- Please use the latest version here-->
<version>3.XX.X</version>
<executions>
<execution>
<id>generate-consumption</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputDirectory>${project.basedir}/edmx</inputDirectory>
<outputDirectory>${project.build.directory}/vdm</outputDirectory>
<deleteOutputDirectory>true</deleteOutputDirectory>
<packageName>com.mycompany.vdm</packageName>
<defaultBasePath>odata/v4/</defaultBasePath>
<compileScope>COMPILE</compileScope>
<serviceMethodsPerEntitySet>true</serviceMethodsPerEntitySet>
<!-- (Optional) You can add a custom copyright header:
<copyrightHeader>Copyright (c) this year, my company</copyrightHeader>

Or use the SAP copyright header:
<sapCopyrightHeader>true</sapCopyrightHeader>
-->
</configuration>
</execution>
</executions>
</plugin>

Adapt the <inputDirectory> to point to the location of your service definitions. A full list of parameters is available here.

Now maven will run the generator within the process-sources phase which is executed before compile. The <compileScope> option instructs maven to add the generated code as sources for the compile phase.

caution

Usually, you will have to override the generated service path in the code. By default, the generator will use the namespace value of the <schema> tag as the service name. The URL path will be built as default-base-path + service-name. If your service definition does not contain this value or the value does not match what is needed in the URL then you need to override the service path in the code. Use the .withServicePath("/path/to/my/service") option on the service class.

Using the CLI​

  1. Download the latest command-line interface (CLI) of the generator from Maven Central. Rename it to odata-generator-cli.jar and put it in a directory of your choice.
  1. Run java -jar odata-generator-cli.jar -i /path/to/input/folder -o /path/to/output/folder. You can also specify the parameter -p "my.package.name" to choose the package name and -b "/my/path" to choose the base path. A full list of parameters is available here.

  2. Put the generated Java source files from the output folder into your project that is using the SAP Cloud SDK so that they are picked up by Java. For example, move them to the application/src/main/java folder.

caution

Usually, you will have to override the generated service path in the code. By default, the generator will use the namespace value of the <schema> tag as the service name. The URL path will be built as default-base-path + service-name. If your service definition does not contain this value or the value does not match what is needed in the URL then you need to override the service path in the code. Use the .withServicePath("/path/to/my/service") option on the service class.

Generate Clients Programmatically​

  1. Please include the odata-v4-generator artifact as a dependency in your project. Choose a module and location from which you intend to invoke the generator and add the following dependency to the appropriate pom.xml.
     <dependency>
    <groupId>com.sap.cloud.sdk.datamodel</groupId>
    <artifactId>odata-v4-generator</artifactId>
    </dependency>
  1. Copy the following code which will later invoke the generator:

    final Path inputDirectory = Paths.get("application/src/main/resources/");
    final Path outputDirectory = Paths.get("application/src/main/java/");
    final Path serviceNameMapping = inputDirectory.resolve("serviceNameMappings.properties");

    new DataModelGenerator()
    .withInputDirectory(inputDirectory.toFile())
    .withOutputDirectory(outputDirectory.toFile())
    .withServiceNameMapping(serviceNameMapping.toFile())
    .pojosOnly(false)
    .withNameSource(NameSource.NAME)
    .withPackageName("org.example")
    .withDefaultBasePath("/my/path/")
    .serviceMethodsPerEntitySet()
    .execute();
  2. Adapt the input & output directory as well as the package name according to your setup. A full list of parameters is available here. Place your EDMX file within the input folder and run the generator.

This should give you the generated classes in the desired folder. You can now proceed with using them to build requests.

In case you run into issues with the above process:

  • Double-check your service and file names
  • Check that the folders are set up correctly
  • The service name mappings meet your expectations
caution

Usually, you will have to override the generated service path in the code. By default, the generator will use the namespace value of the <schema> tag as the service name. The URL path will be built as default-base-path + service-name. If your service definition does not contain this value or the value does not match what is needed in the URL then you need to override the service path in the code. Use the .withServicePath("/path/to/my/service") option on the service class.

Available Parameters​

The following parameters are available on the generator for both OData protocol versions:

ParameterDefaultDescription
<compileScope>NONEAdds the generated sources to the compilation or test phase
<copyrightHeader>nullCopyright header to be added at the top of generated files
<deleteOutputDirectory>FalseTarget directory is deleted before code generation
<defaultBasePath>-Base path of the exposed API
<includeEntitySets>-Only generate classes for specific entity sets
<includeFunctionImports>-Only generate classes for specific function imports
<inputDirectory>inputLocation of the metadata files
<namingStrategy>-Fully-qualified Java class to be used as the naming strategy
<nameSource>LABELSource for entity and property names (either LABEL or NAME)
<outputDirectory>outputOutput directory for generated sources
<overwriteFiles>FalseOverwrite existing files
<packageName>-Package name for the generated sources
<sapCopyrightHeader>FalseAdd the SAP copyright header (overrides copyrightHeader)
<serviceNameMappingFile>-Determine service names from a given mapping file
<serviceMethodsPerEntitySet>FalseGenerate service methods per each entity set for one entity type

More information is also available in the Javadoc of the generator implementation (OData v2, OData v4).

Available Naming Strategies​

The SAP Cloud SDK offers two different naming strategies that can be used out-of-the-box:

  • com.sap.cloud.sdk.datamodel.odata.utility.S4HanaNamingStrategy (default)
  • com.sap.cloud.sdk.datamodel.odata.utility.SimpleNamingStrategy

While both strategies, of course, generate syntactically valid Java names, the S4HanaNamingStrategy tries to make the names as aligned with common Java coding convention as possible. This is achieved by stripping away common pre- and suffixes used in SAP service specifications, such as the prefix SAP_ or the suffix Type. Furthermore, some names are even extended by, for example, adding the prefix to to indicate a navigation property.

In contrast to that, the SimpleNamingStrategy performs only the bare minimum of modifications to convert the specified names into valid Java syntax.

Rate this page