You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using the generator is creates all the necessary types and query/projection classes. But there is one drawback, when only using fields from the interface you still have to do a projection against one of the types, cause the interface doesn't define a default implementation: .projection(p -> p.value().onMoney().centAmount()). The onMoney method in this case creates a projection query like this:
The __typeName field here is important to be able to correctly deserialize the polymorphic type:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "__typename"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = HighPrecisionMoney.class, name = "HighPrecisionMoney"),
@JsonSubTypes.Type(value = Money.class, name = "Money")
})
public interface BaseMoney {
Without the call to the on-method the __typeName field will not be queried and the deserializer fails with
Caused by: com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.commercetools.graphql.api.types.BaseMoney]: missing type id property '__typename' (for POJO property 'value')
Adding the attribute defaultImpl to the BaseMoneys JsonTypeInfo and generating a defaultImpl class sufficient for the interface this would save the necessary call to one of the on methods in the projection .projection(p -> p.value().centAmount()) cause now the deserializer knows which class to instantiate in case there is no discriminator property available in the response.
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "__typename",
defaultImpl = BaseMoneyImpl.class // <--- add this line
)
@JsonSubTypes({
@JsonSubTypes.Type(value = HighPrecisionMoney.class, name = "HighPrecisionMoney"),
@JsonSubTypes.Type(value = Money.class, name = "Money")
})
public interface BaseMoney {
Generate additionally this class as default implementation of the interface
@JsonTypeInfo(
use = JsonTypeInfo.Id.NONE
)
public class BaseMoneyImpl implements BaseMoney {
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
The code generator supports polymorphic interfaces like the one below:
Using the generator is creates all the necessary types and query/projection classes. But there is one drawback, when only using fields from the interface you still have to do a projection against one of the types, cause the interface doesn't define a default implementation:
.projection(p -> p.value().onMoney().centAmount())
. TheonMoney
method in this case creates a projection query like this:The __typeName field here is important to be able to correctly deserialize the polymorphic type:
Without the call to the
on
-method the __typeName field will not be queried and the deserializer fails withAdding the attribute
defaultImpl
to the BaseMoneys JsonTypeInfo and generating a defaultImpl class sufficient for the interface this would save the necessary call to one of theon
methods in the projection.projection(p -> p.value().centAmount())
cause now the deserializer knows which class to instantiate in case there is no discriminator property available in the response.Generate additionally this class as default implementation of the interface
Beta Was this translation helpful? Give feedback.
All reactions