web-dev-qa-db-fra.com

Insertion d'un objet Java dans une collection MongoDB à l'aide de Java

J'essaie d'insérer un objet Java entier dans une collection MongoDB à l'aide de Java. Je reçois l'erreur suivante:

Erreur :

Exception in thread "main" Java.lang.IllegalArgumentException: can't serialize class net.yogesh.test.Employee
    at org.bson.BSONEncoder._putObjectField(BSONEncoder.Java:185)
    at org.bson.BSONEncoder.putObject(BSONEncoder.Java:119)
    at org.bson.BSONEncoder.putObject(BSONEncoder.Java:65)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.Java:176)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.Java:134)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.Java:129)
    at com.mongodb.DBCollection.save(DBCollection.Java:418)
    at net.yogesh.test.test.main(test.Java:31)

Emplyoee.Java (POJO)

package net.yogesh.test;

import Java.io.Serializable;

public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;
    private long no;
    private String name;

    public Employee() {
    }

    public long getNo() {
        return no;
    }

    public void setNo(long no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Main Method Class (test.Java)

package net.yogesh.test;

import Java.net.UnknownHostException;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
import com.mongodb.MongoException;

public class test {

    public static void main(String[] args) throws UnknownHostException,
            MongoException {

        Mongo mongo = new Mongo("localhost", 27017);
        DB db = mongo.getDB("test");

        Employee employee = new Employee();
        employee.setNo(1L);
        employee.setName("yogesh");


        BasicDBObject basicDBObject = new BasicDBObject("Name", employee);

        DBCollection dbCollection = db.getCollection("NameColl");

        dbCollection.save(basicDBObject);   

    }

}

Quelqu'un peut-il expliquer pourquoi je reçois cette erreur?

28
Yogesh Prajapati

Je suis un peu confus quant à la raison pour laquelle vous penseriez que cela fonctionnerait en premier lieu. Quelque chose doit savoir comment mapper votre POJO sur un document MongoDB. Actuellement, vous ne dites à aucune partie du système comment faire cela.

Vous pouvez soit utiliser une bibliothèque de mappage pour cela (Morphia vient à l’esprit), soit utiliser ReflectionDBObject. L’une ou l’autre solution (la première beaucoup mieux que la seconde) vous permet de mapper des POJO à des documents MongoDB et inversement.

29
Remon van Vliet

Pro 
vous continuez à travailler avec des objets fortement typés comme vous le souhaitiez

Contra
Certaines personnes n'aiment vraiment pas: s'étend


package foo;
import com.mongodb.BasicDBObject;

public class Employee extends BasicDBObject {

private static final long serialVersionUID = 2105061907470199595L;
//should be something shorter as "name" like "n" 
//here just use name to conform your  sample
public static final String NAME = "name";
public static final String NO = "no";
public static final String COLLECTION_NAME = "employee";

public Long getNo() {
    return getLong(NO);
}

public void setNo(long no) {
    put(NO, no);
}

public String getName() {
    return getString(NAME);
}

public void setName(String name) {
    put(NAME, name);
}

} </ pre> </ code>


package foo;
import Java.net.UnknownHostException;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
import com.mongodb.MongoException;

public class Test {

public static void main(String[] args) throws UnknownHostException,
        MongoException {

    Mongo mongo = new Mongo("localhost", 27017);
    DB db = mongo.getDB("yeahMongo");

    Employee employee = new Employee();
    employee.setNo(1L);
    employee.setName("yogesh");

    DBCollection employeeCollection = null ;
    employeeCollection = db.getCollection(Employee.COLLECTION_NAME);

    employeeCollection.save(employee);

    System.err.println(employeeCollection.findOne());

}

} </ pre> </ code>

En plus de morphia, vous devriez jeter un coup d'œil à Jongo: http://jongo.org/ Jongo utilise la même syntaxe de formulaire que le moteur js mongo, et je l'ai trouvé très utile pour un débutant. Vous n'êtes pas obligé de changer votre carte mentale entre mongojs et Java. vous pouvez utiliser l'exemple js avec de petites modifications.

21
Damien MIRAS
DB db = mongoClient.getDB( "mydb" );

coll = db.getCollection("testCollection");

Employee emp = new Employee();
emp.setId("1001");
emp.setName("John Doe");

//Converting a custom Class(Employee) to BasicDBObject
Gson gson = new Gson();
BasicDBObject obj = (BasicDBObject)JSON.parse(gson.toJson(emp));
coll.insert(obj);
findEmployee(new BasicDBObject("id","1001"));


public static void findEmployee(BasicDBObject query){

    DBCursor cursor = coll.find(query);

    try {
       while(cursor.hasNext()) {
          DBObject dbobj = cursor.next();
        //Converting BasicDBObject to a custom Class(Employee)
          Employee emp = (new Gson()).fromJson(dbobj.toString(), Employee.class);
          System.out.println(emp.getName());
       }
    } finally {
       cursor.close();
    }

}

Je pensais qu'il serait utile de poster du code qui effectue des conversions dans les deux sens.
Stocker un objet employé
Trouver et recréer un objet employé
J'espère que cela vous sera utile.

19
user1456599

Vous pouvez convertir votre objet Java en chaîne json à l'aide de la bibliothèque gson puis l'insérer dans mongodb.

Par exemple:

Gson gson = new Gson();
String json = gson.toJson(Employee);    
BasicDBObject basicDBObject = new BasicDBObject("Name", json );          
DBCollection dbCollection = db.getCollection("NameColl");          
dbCollection.save(basicDBObject);    
13
vikasse

Avec MongoDB, vous ne pouvez pas insérer votre bean Java dans la base de données, mais vous devez les remapper en objet MongoDB.

Dans votre cas, vous devez faire:

BasicDBObject basicDBObject = new BasicDBObject();
basicDBObject.put("no", employee.getNo());
basicDBObject.put("name", employee.getName());
6
dash1e

Il y a eu plusieurs changements depuis que cette question a été posée. En utilisant test.Java dans la question, voici ce qui a fonctionné pour moi avec la Gson de Google: 

import com.google.gson.Gson;
import com.mongodb.Block;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

public class test {
  public static void main(String[] args) {
    MongoClient mongoClient = new MongoClient(); // Connect with default settings i.e. localhost:27017
    MongoDatabase db = mongoClient.getDatabase("test"); // Get database "test". Creates one if it doesn't exist
    Employee employee = new Employee(); // Create Java object
    employee.setNo(1L);
    employee.setName("yogesh");
    // Deserialize object to json string
    Gson gson = new Gson();
    String json = gson.toJson(employee);
    // Parse to bson document and insert
    Document doc = Document.parse(json);
    db.getCollection("NameColl").insertOne(doc);

    // Retrieve to ensure object was inserted
    FindIterable<Document> iterable = db.getCollection("NameColl").find();
    iterable.forEach(new Block<Document>() {
      @Override
      public void apply(final Document document) {
        System.out.println(document); // See below to convert document back to Employee
      }
    });

  }
}

Vous pouvez également utiliser Gson pour reconvertir le document bson récupéré en objet Java:

Gson gson = new Gson();
Employee emp = gson.fromJson(document.toJson(), Employee.class);
5
kubuntu

Peut-être pouvez-vous utiliser une API spécialisée du framework Object Document Mapping telle que Moprphia

2
fiction

J'espère que cela fonctionnera pour vous et que vous pourrez obtenir de l'aide à ce sujet .

  1. Classe de connexion à la base de données

Connection.Java

package test;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.PojoCodecProvider;
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.client.MongoDatabase;

public class Connection {
    public MongoClient mongo;
    private String db;
    public MongoDatabase database;
    private static Connection instance;

    private Connection() {
        db = "chatsystem";
        CodecRegistry pojoCodecRegistry = fromRegistries(MongoClient.getDefaultCodecRegistry(),
                fromProviders(PojoCodecProvider.builder().automatic(true).build()));
        mongo = new MongoClient("localhost", MongoClientOptions.builder().codecRegistry(pojoCodecRegistry).build());
        database = mongo.getDatabase(db);

    }

    public static Connection getInstance() {
        if (instance == null) {
            instance = new Connection();
            return instance;
        } else {
            return instance;
        }
    }

}
  1. Classe de modèle

Person.Java

package test;

import org.bson.types.ObjectId;

public class Person {

    public Person() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public String getLname() {
        return lname;
    }

    public void setLname(String lname) {
        this.lname = lname;
    }

    private ObjectId id;

    public Person(String username, String email, String password, String fname, String lname) {
        super();
        this.username = username;
        this.email = email;
        this.password = password;
        this.fname = fname;
        this.lname = lname;
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    private String username;
    private String email;
    private String password;
    private String fname;
    private String lname;
}
  1. Classe principale

test.Java

package test;

import Java.util.ArrayList;
import Java.util.Iterator;
import Java.util.List;
import static com.mongodb.client.model.Filters.*;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;

public class test {
    private MongoCollection<Person> person;
    Connection conn;
    public void getCollection() {
        conn = Connection.getInstance();
        person = conn.database.getCollection("person", Person.class);
    }
    public static void main(String[] args) throws Exception {
        test t = new test();
        t.getCollection();
        Person p = new Person();
        p.setEmail("[email protected]");
        p.setFname("ftest");
        p.setLname("ltest");
        p.setPassword("testtest");
        p.setUsername("test123");


        // insert person type objects in database
        t.insertPerson(p);


        // get all persons from database
        List<Person> pp = t.getAllPersons();
        Person pt = pp.get(0);
        System.out.println(pt.getEmail());
        System.out.println(pt.getId());


        // get one person from database by username filter

                 // pass username of person in method argument
        Person ph = t.getOnePerson("test123");
        System.out.println(ph.getEmail());
        System.out.println(ph.getId());


        // update/edit person by username filter
                // pass username of person in method argument
        t.updatePerson("test123");


        // delete person by username filter
               // pass username of person in method argument
        t.removePerson("updatetest123");

    }

    public void insertPerson(Person p) {

        person.insertOne(p);
    }

    public List<Person> getAllPersons() {
        FindIterable<Person> iterable = person.find();
        Iterator it = iterable.iterator();
        List<Person> allPersons = new ArrayList<>();
        while (it.hasNext()) {
            Person per = (Person) it.next();
            allPersons.add(per);
        }
        return allPersons;
    }

    public Person getOnePerson(String username) {
        return person.find(eq("username", username)).first();
    }

    public void updatePerson(String username) {
        Person p = new Person();
        p.setEmail("[email protected]");
        p.setFname("updateftest");
        p.setLname("updateltest");
        p.setPassword("updatetesttest");
        p.setUsername("updatetest123");
        person.replaceOne(eq("username", username), p);

    }

    public void removePerson(String username) {
        person.deleteOne(eq("username", username));
    }



}
1
faizan ahmad

Utilisez BasicDBObjectBuilder pour convertir votre POJO en une instance de DBObject qu'un DBCollection peut enregistrer:

import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject;

public class Employee {
    private long no;
    private String name;

    // Getters and Setters

    public DBObject toDBObject() {
        BasicDBObjectBuilder builder = BasicDBObjectBuilder
                .start("no", no)
                .append("name", name);
        return builder.get();
    }
}

Pour sauvegarder, il suffit d'appeler toDBObject() sur l'instance de POJO et de le fournir à la collection:

public class test {

    public static void main(String[] args) throws UnknownHostException,
            MongoException {
        ...
        DBCollection dbCollection = db.getCollection("NameColl");

        Employee employee = new Employee();
        employee.setNo(1L);
        employee.setName("yogesh");

        dbCollection.save(employee.toDBObject());
    }
}

En utilisant cette approche:

  • Vous n'avez pas besoin de créer manuellement une DBObject à chaque fois
  • Vous n'avez pas besoin de gâcher votre POJO en prolongeant les cours de Mongo (et si votre POJO étend déjà un cours?) 
  • Vous n'avez pas besoin d'un mappeur Json [et de ses annotations sur les champs POJO]
  • Vous ne dépendez que de jar Java-mongo-driver 
1
Omid

Je recommande vivement MongoJack , une bibliothèque appropriée pour mapper des objets Java avec/à partir de documents MongoDB.

Le code serait quelque chose comme ci-dessous:

import Java.util.Arrays;
import org.mongojack.JacksonDBCollection;
import com.mongodb.DB;
import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;

public class Test {

    public static void main(String[] args) {

        MongoClient mongoClient = new MongoClient(Arrays.asList(new ServerAddress("localhost", 27017)));
        DB db = mongoClient.getDB("test");

        Employee employee = new Employee();
        employee.setNo(1L);
        employee.setName("yogesh");

        JacksonDBCollection<Employee, String> collectionData = JacksonDBCollection.wrap(db.getCollection("NameColl"), Employee.class, String.class);
        collectionData.save(employee);
        mongoClient.close();
    }

}

(PS: Actuellement, j'utilise mongo-Java-driver v3.2.2 et mongojack v2.6.1)

1
Yuci

Utilisez simplement la méthode "insertOne", pas de sauvegarde. 

    MongoCollection collection;
    String collectionName = "somename";
    String jsonObject = "{}";

    if (!mongoTemplate.collectionExists(collectionName)) {
        collection = mongoTemplate.createCollection(collectionName);
        logger.info("Collection %s was successfully created", collectionName);
    } else {
        collection = mongoTemplate.getCollection(collectionName);
    }

    collection.insertOne(Document.parse(jsonObject));
0
Stas

J'ai la même erreur lorsque j'essaie d'insérer un objet Java BasicDBObject dans une collection MongoDb.

Mon objet est créé à partir d'un fichier XML converti en Json.

Java.lang.IllegalArgumentException: can't serialize class net.sf.json.JSONNull
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.Java:299)
    at org.bson.BasicBSONEncoder.putMap(BasicBSONEncoder.Java:339)
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.Java:261)

Cette erreur est due à des balises vides dans XML. quand j'ai enlevé toutes les balises vides, je l'ai résolu.

0
Luigi

Plus tard mais plus tard, l’insertion directe de haricots est possible à partir de Mongod 3.5.

0
M. Gopal