-
Type: Question
-
Resolution: Done
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
Java Driver Version: 4.7
Why is there a difference in behavior between using @BsonProperty("_id") and @BsonId in the constructor of a model annotated with @BsonCreator?
- I saw issues when try to deserialize a document from the DB into the following model
I was getting the following error:
"Can't find a codec for class com.xgen.cloud.services.authz._private.model.aggregation.PermissionUsageCount"
Document from the DB
{ _id: { service: String, type: String, action: String }, numUsages: long }
Model's constructor
@BsonCreator public PermissionUsageCount( @BsonId final Permission id, @BsonProperty("numUsages") final long numUsages) { this.id = id; this.numUsages = numUsages; }
Notably, the model did not have any getters or settings on the ID field. Permission was defined as Model with the standard constructor using @BsonProperty annotations for each field in the document above
When I updated the constructor to the following I no longer saw any issues
@BsonCreator public PermissionUsageCount( @BsonProperty("_id") final Permission id, @BsonProperty("numUsages") final long numUsages) { this.id = id; this.numUsages = numUsages; }
In addition adding any of the following things while using @BsonId in the constructor also worked
- A getter on the corresponding field (following Java Bean naming conventions)
- A setter on the corresponding field (following Java Bean naming conventions)
- A BsonProperty("_id") annotation on the instance variable itself
Looking at the java driver's documentation is says you need to have all parameters in a @BsonCreator constructor, but it looks like that is not the case as well: https://www.mongodb.com/docs/drivers/java/sync/current/fundamentals/data-formats/pojo-customization/#annotations
So it looks like there is some gap in functionality between using @BsonProperty("_id") and @BsonId that adding any of the following three mentioned above.
The docs for @BsonId are pretty scarce only summarizing the annotation as doing the following: "Marks a property to serialize as the _id property." But it can be used as a way to deserialize the _id property from the DB as well. It might be good to have one of the following things added or clarified in the documentation * Can @BsonId be used in a @BsonCreator constructor to deserialize a document from the DB? If so in what conditions?
- What functional difference is there between @BsonId and @BsonProperty("_id")
Also if there is a desire to have no functional difference between @BsonId and @BsonProperty("_id") it would be good to address the current gap in functionality