-
Type: Bug
-
Resolution: Works as Designed
-
Priority: Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: POJO
-
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.