0

The generator has created a field of type OffsetDateTime:

@Nullable
@ElementName("DocDate")
private OffsetDateTime docDate;

But the server actually returns dates in the format: YYYY-mm-dd i.e. 2021-03-07

When using the generated code I get the following warnings:

WARN - Not deserializable: 2021-03-07

What is the correct way to override the deserialization of these fields? Or have these fields deserialize correctly?

Conner
  • 17
  • 5
  • Hi Connner, welcome to SO. Is the service OData V4? Also, is the field in the service defined as Edm.DateTimeOffset? – MatKuhr Mar 12 '21 at 15:45

1 Answers1

0

An OffsetDateTime should have both a date and a time. The data your service responds with is lacking the time part. As per the OData V4 ABNF, this is not allowed (assuming your service is a V4 service):

dateTimeOffsetValue = year "-" month "-" day "T" hour ":" minute [ ":" second [ "." fractionalSeconds ] ] ( "Z" / SIGN hour ":" minute )

One way to solve this is to change the property type. You could either:

  1. Change it to Edm.Date in the specification
  2. Or change it to LocalDate in the generated code.

Of course this only makes sense if the service will always respond with a date.


Edit: If you really need to register a custom type adapter (e.g. because the service violates the JSON format) you could override the GsonVdmAdapterFactory:

public <T> TypeAdapter<T> create( @Nonnull final Gson gson, @Nonnull final TypeToken<T> type )
{
    if( LocalDate.class.isAssignableFrom(rawType) ) {
        return (TypeAdapter<T>) new CustomLocalDateTypeAdapter();
    } else {
        return super.create(gson, type);
    }
}

However, this also requires changing the generated code, because there is currently no convenience to pass a custom type adapter as parameter. Change @JsonAdapter(com.sap.cloud.sdk.datamodel.odatav4.adapter.GsonVdmAdapterFactory.class) to reference your custom factory.

Still, I'd recommend using one of the above workarounds until the service is fixed.

MatKuhr
  • 505
  • 4
  • 13
  • The SAP B1 definition lists it as `` but actually returns dates without any time information. I can modify the generated code to reflect it. I was wondering if there were a more elegant way of handling this but the above works. – Conner Mar 12 '21 at 16:24
  • If the service always responds with a `Date` then I think adapting the spec until it is fixed by the service is the best way to go. If for some reason the existing parsing logic is not a solution, I expanded my answer on how to register custom type adapters if it is absolutely necessary. – MatKuhr Mar 15 '21 at 08:51
  • 1
    Makes sense, unfortunately I don't think this spec will be changed anytime soon. I'll just keep modifying the client code as needed. Thanks for the help! – Conner Mar 18 '21 at 16:05