commercetools / commercetools-sdk-java-v2

The e-commerce SDK from commercetools for Java.
https://commercetools.github.io/commercetools-sdk-java-v2/javadoc/index.html
Apache License 2.0
35 stars 16 forks source link

Cart discount query all cart discounts using composable API not working #744

Open artofvijay opened 1 month ago

artofvijay commented 1 month ago

Hi, While querying cart discounts using composable API getting an exception below. can you pls advice.

        var cartDiscountQuery = apiRoot.cartDiscounts().get();
        List<CartDiscount> cartDiscounts = new ArrayList<>();
        queryAll(cartDiscountQuery, (Consumer<List<CartDiscount>>) cartDiscounts::addAll).toCompletableFuture().join();

Exception io.vrap.rmf.base.client.DeserializationException: Could not resolve subtype of [simple type, class com.commercetools.api.models.product.ProductReference]: missing type id property 'typeId' (for POJO property 'product')\n at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION disabled); line: 1, column: 478] (through reference chain: com.commercetools.api.models.cart_discount.CartDiscountPagedQueryResponseImpl[\"results\"]->java.util.ArrayList[0]->com.commercetools.api.models.cart_discount.CartDiscountImpl[\"value\"]->com.commercetools.api.models.cart_discount.CartDiscountValueGiftLineItemImpl[\"product\"])","stack_trace":"c.f.j.d.e.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.commercetools.api.models.product.ProductReference]: missing type id property 'typeId' (for POJO property 'product')\n at [Source: REDACTED (StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION disabled); line: 1, column: 478] (through reference chain: com.commercetools.api.models.cart_discount.CartDiscountPagedQueryResponseImpl[\"results\"]->java.util.ArrayList[0]->com.commercetools.api.models.cart_discount.CartDiscountImpl[\"value\"]->com.commercetools.api.models.cart_discount.CartDiscountValueGiftLineItemImpl[\"product\"])\r\n\tat c.f.j.d.e.InvalidTypeIdException.from(InvalidTypeIdException.java:43)\r\n\tat c.f.j.d.DeserializationContext.missingTypeIdException(DeserializationContext.java:2050)\r\n\tat c.f.j.d.DeserializationContext.handleMissingTypeId(DeserializationContext.java:1622)\r\n\tat c.f.j.d.j.i.TypeDeserializerBase._handleMissingTypeId(TypeDeserializerBase.java:307)\r\n\tat c.f.j.d.j.i.AsPropertyTypeDeserializer._deserializeTypedUsingDefaultImpl(AsPropertyTypeDeserializer.java:211)\r\n\tat c.f.j.d.j.i.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:145)\r\n\tat c.f.j.d.d.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1380)\r\n\tat c.f.j.d.d.SettableBeanProperty.deserialize(SettableBeanProperty.java:542)\r\n\tat c.f.j.d.d.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:570)\r\n\tat c.f.j.d.d.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:440)\r\n\tat c.f.j.d.d.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1493)\r\n\tat c.f.j.d.d.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)\r\n\tat c.f.j.d.d.BeanDeserializer._deserializeOther(BeanDeserializer.java:220)\r\n\tat c.f.j.d.d.BeanDeserializer.deserialize(BeanDeserializer.java:187)\r\n\tat c.f.j.d.j.i.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:170)\r\n\tat c.f.j.d.j.i.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTy...\r\n"}

jenschude commented 1 month ago

Based on the stacktrace there seems to be some CartDiscount with a GiftLineItem and a reference to a product, which is not being correctly deserialized as it has no typeId field. Could you take a look and post the json for it?

jenschude commented 1 month ago

I actually could reproduce it, when creating a cartdiscount with a ResourceIdentifier to an product which didn't had a typeId set.

I will open a bug ticket for the API.

Nevertheless I may be able to fix this in the SDK by adjusting the ObjectMapper

You could to this too in the mean time by customizing the ResponseSerializer:

ObjectMapper objectMapper = JsonUtils.createObjectMapper()
        .configure(MapperFeature.REQUIRE_TYPE_ID_FOR_SUBTYPES, false);
ApiRootBuilder.of()
        .withSerializer(ResponseSerializer.of(objectMapper))
        ...;
artofvijay commented 1 month ago

Thank you for the solution. We are planning to go with GraphQL using the below query & java code. Thanks again.

 query getAllCartDiscounts {
              cartDiscounts(limit: 50) {
                total
                offset
                count
                results {
                  key
                  value {
                    type
                    __typename
                    ... on GiftLineItemValue {
                      type
                      productRef {
                        typeId
                        id
                      }
                    }
                  }
                }
              }
            }
 //Prepare GraphQL Request
 GraphQLRequest<CartDiscountQueryResult> request = GraphQLRequest.builder()
                .query(GQL_QUERY_CART_DISCOUNTS)
                .dataMapper(GraphQLData::getCartDiscounts)
                .build();

 // Execute GraphQL query
 GraphQLResponse<CartDiscountQueryResult> response = projectApiRoot.graphql()
                .query(request)
                .executeBlocking()
                .getBody();

 // Error check and response handling       
 List<CartDiscount> cartDiscountsList = response.getData().getResults()