4 / 4
Jul 2024

I am new to MongoDb and am having a problem getting the _id field in Mongo to populate in a pojo when the user field is in a parent class. Other fields in the parent class populate just fine. I am trying to figure out what I need to do to get this to work. When I eliminate the parent class, and move everything to a single class, then the _id field is populated just fine.

I’ve reproduced the problem in a simple bit of test code, but I can’t upload, so embedding here. Basically, an abstract parent class with the id field and another field, then a child pojo with a single field which extends the abstract class.

import org.bson.codecs.pojo.annotations.BsonId; import org.bson.codecs.pojo.annotations.BsonProperty; import org.bson.types.ObjectId; public abstract class AbstractPojo { private ObjectId id; private String parentValue; public AbstractPojo() { } @BsonId @BsonProperty("_id") public ObjectId getId() { return id; } public void setId(ObjectId id) { this.id = id; } @BsonProperty("parentValue") public String getParentValue() { return parentValue; } public void setParentValue(String parentValue) { this.parentValue = parentValue; } } import org.bson.codecs.pojo.annotations.BsonProperty; public class TestPojo2 extends AbstractPojo { private String value; public TestPojo2() { } @BsonProperty("value") public String getValue() { return value; } public void setValue(String value) { this.value = value; } } public static void main(String[] args) { try { TestMongoDbInstance.start(); // Configuration MongoClientSettings clientSettings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString(TestMongoDbInstance.getConnectionString())) .build(); PojoCodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build(); CodecRegistry codecRegistry = CodecRegistries.fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), CodecRegistries.fromProviders(pojoCodecProvider)); MongoClient mongoClient = MongoClients.create(clientSettings); MongoDatabase mongoDb = mongoClient.getDatabase("testdb").withCodecRegistry(codecRegistry); // Insert an instance TestPojo2 obj = new TestPojo2(); obj.setValue("Some Value"); obj.setParentValue("Some Common Value"); InsertOneResult insRes = mongoDb.getCollection("coll", TestPojo2.class).insertOne(obj); System.out.println("InsertedId: " + insRes.getInsertedId().asObjectId()); // Read the instance FindIterable<TestPojo2> readRes = mongoDb.getCollection("coll", TestPojo2.class).find(); TestPojo2 readObj = readRes.first(); System.out.println("Read Instance: "); System.out.println(" id: " + readObj.getId()); System.out.println(" value: " + readObj.getValue()); System.out.println(" parentValue: " + readObj.getParentValue()); } catch (Exception ex) { ex.printStackTrace(); } finally { try { TestMongoDbInstance.stop(); } catch (Exception e) { System.err.println("Failed stopping Mongo"); e.printStackTrace(); } } }

When I run this, what I get in the console is;

InsertedId: BsonObjectId{value=6682e39975b35503dac3253f} Read Instance: id: null value: Some Value parentValue: Some Common Value

If I use mongosh to look at the object directly in mongo, this is what is there;

testdb> db.coll.find() [ { _id: ObjectId('6682e39975b35503dac3253f'), parentValue: 'Some Common Value', value: 'Some Value' } ]

As I mentioned above, if I eliminate the abstract parent class and collapse the _id field directly in to the pojo it works just fine.

Is there something I am missing with this? I am still trying to figure out the annotations and configuration, maybe I am missing something there that would help with this.

I appreciate all the help I can get!

Hi @Scott_A_Stanley and welcome to the community forum.

The issue seem to be with the annotations being used with the _id in the above code. I would recommend you going through the code example available on Java-Mapping POJOs to get started and understand how the annotations have been made.

Please reach out in case you have issue while following the article.

Regards
Aasawari

@Aasawari I am not sure I see what the issue is with the annotations on the _id that you are referring to. The Java-Mapping POJOs quickstart does not really talk about mapping the ID attribute, so does not discuss the BsonId annotation. Are you referring to the fact I wrote the annotations as

@BsonProperty("_id")

instead of

@BsonProperty(value = "_id")

??

If so, the value = is optional when the annotation is single valued and the element is called value, Java Tutorials : Annotation Basics.

I did modify my test code to add the value = on all of my BsonProperty annotations just to make sure and I see the same behavior as before.