javaspringmongodbmorphia

Mongo 4 ChangeStreamDocument<POJO> fails to cast to Morphia POJO at runtime but compiles fine


I have a Mongo ChangeStream listener using a Consumer:

private final Consumer<ChangeStreamDocument<POJO>> log = el -> {
    LOG.info("{} deserialized Changestream Doc with wrapper: {}", this.collection, el.toString());
    LOG.info("{} actual document object: {}", this.collection, el.getFullDocument());

    // runtime exceptions on the following lines:
    LOG.info("{} class of document object: {}", this.collection, el.getFullDocument().getClass());
    LOG.info("{} id of POJO document as fetched through POJO getter: {}", this.collection, el.getFullDocument().getId());
  };

The version of the Mongo driver I'm using is org.mongodb:mongodb-driver-core:4.2.3

Even though java successfully compiles this code (and assumes .getFullDocument() is returning a POJO.class, it fails during runtime with java.lang.ClassCastException: class org.bson.Document cannot be cast to class ...POJO.class.

The POJO's model is 1:1 with the document model. The only thing the POJO has is Morphia annotations (which I cannot work around), ie @Entity(POJO.COLLECTION_NAME). Is there any clean way to have this deserialize properly? Especially since this is runtime, not compile time.


Solution

  • I was able to solve this by recognizing why the POJOMapper from Mongo was not working.

    The POJOCodecProvider enforces that all getters and setters have the same type. The Morphia model I'm working with unfortunately wraps some getters with an Optional. This breaks the POJO codec which forced me to define a custom codec for this type.

    No type checking is enforced at compile type with the ChangeStreamDocument<?>