Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-5128

Add annotations to support default values for primitive types

    • Type: Icon: New Feature New Feature
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 4.10.0
    • Component/s: POJO
    • Labels:
      None

      Summary

      If a Record evolves by gaining a new component, the RecordCodec will trigger an IllegalArgumentException in case of a new primitive component, as the missing field is translated into null.

      Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

      4.10.0, standalone, running in Docker

      How to Reproduce

      // INITIAL/STORED RECORD
      public record Aspect(@BsonId @BsonRepresentation(BsonType.OBJECT_ID)
                           String id,
                           Long legacyId,
                           int order) implements Serializable { }
      
      
      // RECORD WITH ADDITIONAL PRIMITIVE FIELD
      public record Aspect(@BsonId @BsonRepresentation(BsonType.OBJECT_ID)
                           String id,
                           Long legacyId,
                           int order,
                           boolean notFitlerable) implements Serializable { }
      

      Any retrieval from a MongoCollection<Aspect> triggers the exception.

      Additional Background

      The newInstance call in https://github.com/mongodb/mongo-java-driver/blob/master/bson-record-codec/src/main/org/bson/codecs/record/RecordCodec.java#L285 will result in an IllegalArgumentException, as the constructorArguments contain null for the new component.

      Caused by: java.lang.IllegalArgumentException
      	at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
      	at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[?:?]
      	at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
      	at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[?:?]
      	at java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[?:?]
      	at org.bson.codecs.record.RecordCodec.decode(RecordCodec.java:285) ~[bson-record-codec-4.10.0.jar:?]
      

      The problem, in my opinion, is that the componentModel uses wrapper types, but the constructor is detected with the original/non-wrapper types, so adding another constructor that uses wrapper types isn't a feasible workaround.

            Assignee:
            jeff.yemin@mongodb.com Jeffrey Yemin
            Reporter:
            ben@netzgut.net Ben Weidig
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: