[JAVA-2750] Pojo codec conversion missing id field Created: 24/Jan/18  Updated: 27/Oct/23  Resolved: 29/Jan/18

Status: Closed
Project: Java Driver
Component/s: POJO
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major - P3
Reporter: Rohit Jain Assignee: Unassigned
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to JAVA-2768 Add annotation to exclude id field fr... Closed
related to JAVA-2769 Ignore idProperty for embedded classes Closed
is related to JAVA-2767 bson: fails decoding when id property... Closed

 Description   

{
    "_id" : 4771902,
    "upc" : "test-upc-v1",
    "reportingCategory" : {
        "id" : 14,
        "department" : "Footwear"
    }
}

My java class looks like

public class Product {
    private Long _id;
    private String upc;
    private ReportingCategory reportingCategory;
}

public class ReportingCategory {
    private Long id;
    private String department;
}

I am using mongo pojo codec for conversion. "id" field under ReportingCategory is being returned as null. Rest every other data is available. I can see that data when I convert it into RawBsonDocument, but seems like it gets lost in pojo conversion.

Seems like, if pojo has any member with name "id" it by defaults map it to "_id" field of mongo document. Here reporting category is sub document which has no "_id" field, and just some field which is happened to be named "id"



 Comments   
Comment by Ross Lawley [ 02/Feb/18 ]

Added JAVA-2768 & JAVA-2769 to add new features so that this scenario can be handled by the default annotations.

Comment by Rohit Jain [ 25/Jan/18 ]

This works, thank you for a work around.

Comment by Ross Lawley [ 25/Jan/18 ]

Hi rohit.jain,

Thats' correct the default conventions, specifically the CLASS_AND_PROPERTY_CONVENTION will treat any _id or id property as the idProperty for a class. As PojoCodecs are for individual classes, the embedded nature of the ReportingCategory is not taken into account, causing the issue.

Why is there a convention to convert id properties into _id fields?

Properties on a class are determined if they are public fields or if they follow the Java Bean Convention. _id is tricky as a property because get_id() does not follow the Java Bean Convention, but users don't want to store two id fields in MongoDB. So the convention is required to prevent this.

Could embedded classes opt out by default? Unfortunately, that ship has sailed and users maybe relying on the current behaviour without knowing it.

How can I work around it?

You could configure the PojoCodecProvider to not use the CLASS_AND_PROPERTY_CONVENTION and just use the ANNOTATION_CONVENTION:

PojoCodecProvider.builder().conventions(asList(ANNOTATION_CONVENTION)).automatic(true).build();

That will stop all id properties being set as the idProperty. If the _id field is private, then you will still need to annotate the getId() method with a @BsonId annotation so that the id property, is mapped to the _id field. Alternatively, you could write a custom convention that handles the setting of the idProperty as required.

I hope that clarifies what is happening and why and also allows you to work around it with the current data.

Ross

Generated at Thu Feb 08 08:57:59 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.