简体   繁体   中英

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)

You cannot simply serialize every class you have in your application with the mongo java driver. Either, you stick to JSON documents and their supported data types (basically string, various numbers, boolean, date) or you actually write a custom codec for your class, so that the internal Bson conversion can work with it.

Only link I found to a basic example unfortunately in German: https://dev-tek.de/lexicon/Entry/64-MongoDB-Anleitung-Custom-codecs-mit-Hilfe-des-DocumentCodecs/ - but maybe the code helps to understand.

Addendum, regarding the comment:

Basically, you can do a conversion yourself manually along the lines of:

Document doc = new org.bson.Document();
doc.put("userName", user.getName());
doc.put("userId", user.getID());
// ... or whatever your user object looks like
// and then:
dbCollection.insert(doc);

Then, you could try external encoding libraries for converting your object to JSON, for example Jackson as detailed in the answer of this question: Converting Java objects to JSON with Jackson

Once you have a JSON string, you can convert it to an org.bson.Document via

org.bson.Document.parse(jsonString)

and write this into the database.

Try using MongoTemplate. Save the java object in mongodb using this template, it will get created in a document form.

https://www.mkyong.com/mongodb/spring-data-mongodb-insert-document/

Example

MongoTemplate mongoTemplate = new MongoTemplate(new MongoClient("<server>"),"<db name>");

User user = new NormalUser();
mongoTemplate.save(user, "<collection>");

Here is the detailed analysis on this issue:-

Looks like "lombok" library adds the boilerplate code (ie 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 (eg 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"
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM