35

我正在尝试使用 Java 将整个 Java 对象插入到 MongoDB 集合中。我收到以下错误:

错误 :

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;
    }

}

主要方法类 (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);   

    }

}

谁能解释我为什么会收到这个错误?

4

12 回答 12

32

我有点困惑,不知道为什么你会认为这首先会起作用。您需要知道的第一件事是如何将您的 POJO 映射到 MongoDB 文档。目前,您没有告诉系统(您的代码)如何做到这一点。

您可以为此使用映射库(想到 Morphia)或使用 ReflectionDBObject。任何一种解决方案都允许您将 POJO 映射到 MongoDB 文档或将 MongoDB 文档映射到 POJO(前一种方式比后者好得多)。

于 2012-04-16T08:05:15.887 回答
26
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();
    }

}

我认为发布双向转换的代码会很有用。
存储员工对象
查找并重新创建员工对象
希望这很有用..

于 2013-12-18T16:42:44.640 回答
21


,您可以继续使用您想要的强类型对象

魂斗罗
有些人真的不喜欢:扩展


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);
}

}


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());

}

}

除了 morphia 你应该看看 jongo: http : //jongo.org/ jongo 使用与 js mongo 引擎相同的表单语法,我发现它对初学者来说非常有用。您不必在 mongojs 和 java 之间切换您的思维导图。您可以使用 js 示例,只需稍作改动。

于 2013-04-18T15:39:30.710 回答
13

您可以使用gson 库将您的 java 对象转换为 json 字符串,然后将其插入 mongodb。

例如:

Gson gson = new Gson();
String json = gson.toJson(Employee);    
BasicDBObject basicDBObject = new BasicDBObject("Name", json );          
DBCollection dbCollection = db.getCollection("NameColl");          
dbCollection.save(basicDBObject);    
于 2012-04-16T13:17:11.523 回答
7

自从提出这个问题以来,已经发生了一些变化。test.java在问题中使用,这是使用谷歌对我有用的Gson

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
      }
    });

  }
}

您还可以使用Gson将检索到的 bson 文档转换回 Java 对象:

Gson gson = new Gson();
Employee emp = gson.fromJson(document.toJson(), Employee.class);
于 2015-10-22T17:57:52.780 回答
6

使用 MongoDB,您不能将 Java bean 插入 DB,但您必须将它们重新映射到 MongoDB 对象。

在您的情况下,您必须执行以下操作:

BasicDBObject basicDBObject = new BasicDBObject();
basicDBObject.put("no", employee.getNo());
basicDBObject.put("name", employee.getName());
于 2012-04-16T08:02:53.593 回答
3

希望这对您有用,并且您可以从中获得帮助。我执行了数据库操作(插入、删除、更新、获取、getall)并使用 Person 对象在 MongoDB 中使用 java 进行操作以进行演示。

  1. 数据库连接类

连接.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. 模型类

人.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. 主班

测试.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("test@test.com");
        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("update@test.com");
        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));
    }



}
于 2018-12-21T14:15:30.510 回答
2

强烈推荐MongoJack,一个不错的库,用于将 Java 对象映射到/从 MongoDB 文档。

代码如下所示:

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:目前我正在使用 mongo-java-driver v3.2.2 和 mongojack v2.6.1)

于 2017-04-11T23:29:45.450 回答
1

使用BasicDBObjectBuilder将您的 POJO 转换为DBCollection可以保存的DBObject实例:

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();
    }
}

为了保存,只需调用toDBObject()POJO 实例并将其提供给集合:

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());
    }
}

使用这种方法:

  • 您无需DBObject每次都手动创建
  • 你不需要通过扩展 Mongo 类来搞乱你的 POJO(如果你的 POJO 已经在扩展一个类怎么办?)
  • 您不需要 Json 映射器 [及其在 POJO 字段上的注释]
  • 你只依赖于 java-mongo-driver jar
于 2017-09-07T04:51:16.423 回答
0

当我尝试将 java BasicDBObject 插入 MongoDb 集合时,我遇到了同样的错误。

我的对象是从转换为 Json 的 Xml 创建的。

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)

此错误是由 Xml 中的空标签引起的;当我删除所有空标签时,我解决了它。

于 2015-07-24T13:12:23.697 回答
0

只需使用“insertOne”方法,不保存。

    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));
于 2018-11-23T13:15:41.727 回答
0

由于没有人提到它 - 我认为使用bson4jackson可能会有解决方案。这标榜自己是一个快速编码器。

于 2021-04-22T15:27:53.993 回答