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?
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.
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.
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.
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);
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());
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);
Peut-être pouvez-vous utiliser une API spécialisée du framework Object Document Mapping telle que Moprphia
J'espère que cela fonctionnera pour vous et que vous pourrez obtenir de l'aide à ce sujet .
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;
}
}
}
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;
}
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));
}
}
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:
DBObject
à chaque foisJe 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)
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));
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.
Plus tard mais plus tard, l’insertion directe de haricots est possible à partir de Mongod 3.5.