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

Bug in docs - Bson annotations have no effect on private fields

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: POJO
    • Labels:
      None
    • Java Drivers

      Summary

      According to the Java driver docs, applying a @BsonProperty to a private POJO field will register it for serializing and allow customising of the name. However, this does not work, with the field being ignored and not saved to the database.

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

      I am using Mongo Java driver 4.10.2.

      How to Reproduce

      Run a local MongoDB server. You can run one using Docker with the following command:

      docker run -p 27017:27017 -d mongo

      Run the following Java code:

      import com.mongodb.ConnectionString;
      import com.mongodb.client.MongoClient;
      import com.mongodb.client.MongoClients;
      import org.bson.BsonType;
      import org.bson.codecs.pojo.PojoCodecProvider;
      import org.bson.codecs.pojo.annotations.*;
      
      import java.util.List;
      
      import static com.mongodb.MongoClientSettings.getDefaultCodecRegistry;
      import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
      import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
      
      public class PojoTest {
           public static void main(String[] args) {
              var connectionString = new ConnectionString("mongodb://localhost:27017/pojo_test");
              try (MongoClient client = MongoClients.create(connectionString)) {
                  var database = client.getDatabase(connectionString.getDatabase())
                                          .withCodecRegistry(fromRegistries(getDefaultCodecRegistry(), fromProviders(PojoCodecProvider.builder().automatic(true).build())));
      
                  database.getCollection("products", Product.class).insertOne(new Product("testModel"));
      
                  System.out.println(database.getCollection("products").find().first().toJson());
               }
          }
      
              @BsonDiscriminator(value = "AnnotatedProduct", key = "_cls")
              public static class Product {
                  @BsonProperty("modelName")
                  private String name;
      
                  @BsonId
                  @BsonRepresentation(BsonType.OBJECT_ID)
                  private String serialNumber;
      
                  @BsonIgnore
                  private List<Product> relatedItems;
      
                  @BsonCreator
                  public Product(@BsonProperty("modelName") String name) {
                      this.name = name;
                  }
          }
      }
      

      The Product class is taken directly from the docs. The print output will look something like this: {"_id":

      {"$oid": "65cef178787f38696219fe0f"}

      , "_cls": "AnnotatedProduct"}

      Additional Background

      As far as I can tell, the issue comes from the PojoBuilderHelper class. A property is only considered serializable if it has a getter, or it is public and non-static. As a result, private fields without getters are ignored. This seems to contradict the example in the docs. Either this is a bug, or the docs need to be clearer that the annotation on the private field only works because there is an unseen getter for that field.

            Assignee:
            ashni.mehta@mongodb.com Ashni Mehta
            Reporter:
            skaterx901@hotmail.com Michael Smith
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: