'MongoDb Java- deeper polymorph tree

I have the following polymorphic structure for objects I want to store in MongoDb:

           InventoryItem (abstract)
             /                   \
      Tracked Item            AmountItem (Abstract)
                                   /             \
                        SimpleAmountItem       ListAmountItem

With: (Full code here (Github))

@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "storedType"
)
@JsonSubTypes({
    @JsonSubTypes.Type(value = SimpleAmountItem.class, name = "AMOUNT_SIMPLE"),
    @JsonSubTypes.Type(value = ListAmountItem.class, name = "AMOUNT_LIST"),
    @JsonSubTypes.Type(value = TrackedItem.class, name = "TRACKED")
})
@BsonDiscriminator
public abstract class InventoryItem<T> extends ImagedMainObject {
    @NonNull
    @NotNull
    private Map<@NonNull ObjectId, @NonNull T> storageMap = new LinkedHashMap<>();
    private final StoredType storedType;
    //...
}


@EqualsAndHashCode(callSuper = true)
@Data
public class TrackedItem extends InventoryItem<Map<@NotBlank String, @NotNull TrackedStored>> {
    //...
}


@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@ValidHeldStoredUnits
public abstract class AmountItem<T> extends InventoryItem<T> {
    //...
}



@EqualsAndHashCode(callSuper = true)
@Data
public class SimpleAmountItem extends AmountItem<AmountStored> {
    //...
}


@EqualsAndHashCode(callSuper = true)
@Data
public class ListAmountItem extends AmountItem<List<@NotNull AmountStored>> {
    //...
}

As shown, TrackedItem can be appropriately handled by Mongo, stored/ retrieved, etc. However, both the ListAmountItem and SimpleAmountItem cannot, with the following error:

Encoding a ListAmountItem: 'ListAmountItem()' failed with the following exception:

Failed to encode 'ListAmountItem'. Encoding 'storageMap' errored with: Can't find a codec for class java.lang.Object.

A custom Codec or PojoCodec may need to be explicitly configured and registered to handle this type.
    at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:105)
    at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:359)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:218)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:519)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
    at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:151)
    at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:91)
    at io.quarkus.vertx.core.runtime.VertxCoreRecorder$13.runWith(VertxCoreRecorder.java:543)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: org.bson.codecs.configuration.CodecConfigurationException: An exception occurred when encoding using the AutomaticPojoCodec.
Encoding a ListAmountItem: 'ListAmountItem()' failed with the following exception:

Failed to encode 'ListAmountItem'. Encoding 'storageMap' errored with: Can't find a codec for class java.lang.Object.

It appears that Mongo can reconcile direct/first descendants of a superclass, but not if the inheritance tree gets any deeper than that. Is this as designed, a bug, or something I can tweak to get around?

It appears to me that Mongo gets stuck on trying to reconcile the Simple/ListAmountItems as a plain AmountItem, which makes sense as why it's failing, but not terribly clear as to how to fix it. The @BsonDiscriminator seems rather simplistic, esp. compared to Jackson.

I'll note that I am implementing this in Quarkus 2.7.5.Final.

Looks like there might be some support for specifying known types, but I don't see an analogous java annotation: https://mongodb.github.io/mongo-csharp-driver/2.6/reference/bson/mapping/polymorphism/



Solution 1:[1]

Looks like I found a bug: https://jira.mongodb.org/projects/JAVA/issues/JAVA-4578

Ideally issue will be fixed once that ticket is completed.

For now, I just flattened my object tree, duplicating some code with the understanding I can move to a more proper state in the future

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1