Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.3k stars 1.96k forks source link

[BUG] Custom ObjectMapper is not applied to query parameters #34715

Open jho424 opened 1 year ago

jho424 commented 1 year ago

Describe the bug The configurable ObjectMapper (https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/cosmos/azure-spring-data-cosmos#spring-boot-starter-data-rest) is applied to the actual entity (e.g. when saving or reading), but not to parameter of a query.

To Reproduce

  1. Define a custom ObjectMapper

    @Bean
    public ObjectMapper cosmosObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);        
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    return objectMapper;
    }
  2. Define a entity including a timestamp as Instant

    @Container(containerName = "exampleContainer")
    public class Example {
    private Instant softDeletedAt;
    }

    As a result of the ObjectMapper configuration the Instant is stored as expected as string representation in the CosmosDB (e.g. "softDeletedAt": "2023-04-12T13:44:48.280775500Z",

  3. Define a query

    public interface ExampleRepository extends CosmosRepository<Example, String> {
    List<Example> findAllBySoftDeletedAtBefore(Instant softDeletedAt);
    }

    When debugging, the parameter is serialized to 1682673720.049267 instead of a the string 2023-04-28T09:22:00.049267Z by using another ObjectMapper Utils.getSimpleObjectMapper(). This leads to the query not returning any results. In other words: Whenever the configured ObjectMapper is different to the default mapper the queries do not work.

Expected behavior The same ObjectMapper should be used when serializing entities and also when passing parameters. Actually the configured ObjectMapper needs to be passed to JsonSerializable.

Setup (please complete the following information):

Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

mkrueger commented 1 year ago

Can't repro the issue. The query works as well as debugging.

My sample project. SampleProject.zip

Is that already fixed?

jho424 commented 1 year ago

Hi @mkrueger,

the issue is related to Azure Spring Data Cosmos, so you need setup the stuff described above. I can also confirm that the issue still appears.

mkrueger commented 1 year ago

@jho424 I'm not really experienced with Spring - can you repro the issue in my sample project or did I make something wrong?

jho424 commented 1 year ago

Hi @mkrueger,

I've created a sample project as requested: SpringDataCosmosDbSample.zip

Prerequisite Access to an Azure Cosmos DB . You need to enter your Cosmos credentials in class CosmosDbConfiguration.

Reproduction Execute the class Application. It

  1. creates and saves a new Customer item (aka entity) in the CosmosDB container customer
  2. fetches all customers by the inherited method findAll as a double-check that the setup (including Spring data) is setup correctly (see console output)
  3. fetches all customers where the Instant is before 2023-05-01T00:00:00Z.

You should get the following output:

1. All persisted customers - the newly created customer is contained:
Customer{id='d6e461d4-3b22-4c03-9ea6-0c48f86beac3', softDeletedAt=2023-04-23T00:00:00Z}
2. Persisted customers where 'softDeletedAt' is before 2023-05-01T00:00:00Z - the newly created customer is missing

The saved customer is missing, but should be returned. This is because the "configurable ObjectMapper (https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/spring/azure-spring-data-cosmos/README.md#spring-boot-starter-data-rest) is applied to the actual entity (e.g. when saving or reading), but not to the Instant parameter of a query.

You can do the cross-check by executing the example and exclude the custom ObjectMapper (e.g. remove @Bean in class ObjectMapperConfiguration).

mkrueger commented 1 year ago

I can now reproduce the issue - thank you.

TheovanKraay commented 1 year ago

@mkrueger any updates on this one?