stack man stack man - 2 months ago 22
Java Question

Can´t create entity in MongoDB

I am brand new to MongoDB, so sorry if the question is basic.

I am trying to get a basic CRUD working with Java basic objects (POJOs), but this code fails. (What is the correct way of doing this? I think it might be close to this):

BasicDBObject document = new BasicDBObject();
document.put("name", user);
dbCollection.insert(document);


This is the message I am getting:

Exception in thread "main" java.lang.IllegalArgumentException: can't serialize class entities.users.NormalUser
at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:270)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:174)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:120)
at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:27)
at com.mongodb.OutMessage.putObject(OutMessage.java:289)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:261)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:226)
at com.mongodb.DBCollection.insert(DBCollection.java:75)
at com.mongodb.DBCollection.insert(DBCollection.java:59)
at com.mongodb.DBCollection.insert(DBCollection.java:104)
at repositories.UsersRepository.createUser(UsersRepository.java:53)
at repositories.UsersRepository.main(UsersRepository.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Answer

Here is the detailed analysis on this issue:-

Looks like "lombok" library adds the boilerplate code (i.e. getter and setter methods for the attributes) during compilation time. I have observed two behaviors while executing the program.

1) Eclipse behavior:-

When I run the program via IDE (e.g. eclipse), the "getter" and "setter" methods were not getting generated. I have got serialization error when I ran the main class. I have decompiled the classes User and NormalUser and checked the content. It doesn't have the "getter" and "setter" methods.

Online Java Decompiler

2) Maven behavior:-

I have used maven commands to build the project and checked the classes User and NormalUser. This time I can see the boilerplate codes being generated. I have executed my Main class and it worked fine.

Solution:-

MongoClient client = new MongoClient();
        MongoDatabase database = client.getDatabase("localhost");
        MongoCollection<Document> normalUserCollection = database.getCollection("normaluser");

        User normalUser = new NormalUser("jack", "mike", "US", "dni", "123", Gender.MALE);

        Document document = new Document();
        document.put("user", document.parse(new ObjectMapper().writeValueAsString(normalUser)));

Mongo Java Driver used:-

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>3.2.2</version>
</dependency>
<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.5</version>
        </dependency>

Output:-

The document has been inserted successfully in MongoDB collection.

{
    "_id" : ObjectId("57d2e4134c1c7b287cde1d30"),
    "user" : {
        "surname" : "mike",
        "address" : "US",
        "dni" : "dni",
        "bankAccount" : "123",
        "admin" : false,
        "name" : "jack",
        "gender" : "MALE"
    }
}