MongoDb Java-更深的多态树

MongoDb Java- deeper polymorph tree

对于要存储在 MongoDb 中的对象,我有以下多态结构:

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

有:(完整代码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>> {
    //...
}

如图所示,TrackedItem 可以由 Mongo 适当地处理、存储/检索等。但是,ListAmountItemSimpleAmountItem 都不能,具有以下内容错误:

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(SynchronousDispatcher.java:261)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess[=14=](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.run(VertxRequestHandler.java:91)
    at io.quarkus.vertx.core.runtime.VertxCoreRecorder.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.

看来 Mongo 可以调和超类的 direct/first 个后代,但如果继承树比这更深,则不会。这是设计的问题、错误还是我可以调整以解决的问题?

在我看来,Mongo 在尝试将 Simple/ListAmountItem 调和为普通的 AmountItem 时卡住了,这对于它失败的原因是有道理的,但不是很清楚如何修复它。 @BsonDiscriminator 似乎相当简单,尤其是。与杰克逊相比。

我会注意到我正在 Quarkus 中实现它 2.7.5.Final

看起来可能支持指定已知类型,但我没有看到类似的 java 注释:https://mongodb.github.io/mongo-csharp-driver/2.6/reference/bson/mapping/polymorphism/

看来我发现了一个错误:https://jira.mongodb.org/projects/JAVA/issues/JAVA-4578

理想情况下,问题会在工单完成后得到解决。

现在,我只是展平了我的对象树,复制了一些代码,我知道我可以在将来移动到更合适的状态