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

Using @BsonId in a @BsonCreator constructor has confusing behavior

    • Type: Icon: Question Question
    • Resolution: Done
    • Priority: Icon: Major - P3 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

       

      1. A getter on the corresponding field (following Java Bean naming conventions)
      2. A setter on the corresponding field (following Java Bean naming conventions)
      3. 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

            Assignee:
            ross@mongodb.com Ross Lawley
            Reporter:
            andrew.marshall@mongodb.com Andrew Marshall
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: