10

When I insert a List into mongodb, there is a problem:

Exception in thread "main" java.lang.IllegalArgumentException: can't serialize class mongodb.Person
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:234)
    at org.bson.BasicBSONEncoder.putIterable(BasicBSONEncoder.java:259)
    at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:198)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:140)
    at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:86)
    at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:27)
    at com.mongodb.OutMessage.putObject(OutMessage.java:142)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:252)
    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:211)
    at com.mongodb.DBCollection.insert(DBCollection.java:57)
    at com.mongodb.DBCollection.insert(DBCollection.java:87)
    at com.mongodb.DBCollection.save(DBCollection.java:716)
    at com.mongodb.DBCollection.save(DBCollection.java:691)
    at mongodb.MongoDB.main(MongoDB.java:45)

the class Person is defined as follows:

class Person{
    private String name;
    public Person(String name){
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

The program is :

        DBCollection coll = db.getCollection("test");
        DBObject record = new BasicDBObject();
        List<Person> persons= new ArrayList<Person>();
        persons.add(new Person("Jack"));
        record.put("person", persons);
        coll.save(record);

I can't find the answer from google, so please help me.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
NOrder
  • 2,483
  • 5
  • 26
  • 44
  • how did u do this @vienna.. Plz help me I am having the same problem. Plz help – shalki Jun 22 '12 at 08:00
  • An observation: one of the benefits of MongoDB is the ability to evolve the schema over time without having to update existing documents with these new fields. You may therefore want to store your objects as documents (ie with a field for name, etc), or if you really want to do a binary serialisation, you might prefer to use something such as Google Protocol Buffers which is a more future-proof way of achieving binary serialisation. – Rich Aug 21 '13 at 09:21

8 Answers8

7

Just implement Serializable interface in Person class.

Also it will be good to define a serialVersionUID in your class.

AFAIK, while creating POJO class in java, the class should be serializable, if it is going to be transfered over some stream, have a default constructor, and allows access to properties/fields using getter and setter methods.

You might be interested in reading this: Discover the secrets of the Java Serialization API

Harry Joy
  • 58,650
  • 30
  • 162
  • 207
  • 1
    But I still have the problem even though I implements the Serializable interface; class Person implements Serializable{ private String name; public Person(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } – NOrder Jan 05 '12 at 06:59
  • @vienna: Did you get the same exception or any other? – Harry Joy Jan 05 '12 at 07:01
  • @vienna: Try adding a default constructor in Person class `public Person(){}`. – Harry Joy Jan 05 '12 at 07:09
  • @vienna, that's because you have only 1 constructor and that takes an argument. A POJO class can have no argument or zero-based argument constructor. I suggest doing what Harry Joy stated above. – Buhake Sindi Jan 05 '12 at 07:26
  • @vienna: Yes extending [BasicDBObject](http://api.mongodb.org/java/2.0/com/mongodb/BasicDBObject.html) solves problem cause BasicDBObject it self implements Serializable. – Harry Joy Jan 05 '12 at 07:33
1

I got the same exception while working with mongodb. I tried making the problematic class serializable but that didn't fix my problem.

Following is what worked for me. Extend the class to be a child of BasicDBObject . Of course this works only if the problem is caused by MongoDB.

extends BasicDBObject 

Original source

http://techidiocy.com/cant-serialize-class-mongodb-illegal-argument-exception/#comment-1298

Pratik Patel
  • 1,305
  • 1
  • 17
  • 44
0

Here is the code example to make Employee object serialized:

public class Employee implements Serializable {

    private int empId;
    private String name;

    public int getEmpId() {
        return empId;
    }

    public String getName() {
        return name;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

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

    @Override
    public String toString() {
        return "EMployee id : " + empId + "  \nEmployee Name : " + name;
    }
}

//Another Main Class
public class Main{
    public static void main(String[] args) 
        throws FileNotFoundException, IOException, ClassNotFoundException {

        String filename = "data.txt";
        Employee e = new Employee();
        e.setEmpId(101);
        e.setName("Yasir Shabbir");

        FileOutputStream fos = null;
        ObjectOutputStream out = null;

        fos = new FileOutputStream(filename);
        out = new ObjectOutputStream(fos);
        out.writeObject(e);

        out.close();

        // Now to read the object from file
        // save the object to file
        FileInputStream fis = null;
        ObjectInputStream in = null;

        fis = new FileInputStream(filename);
        in = new ObjectInputStream(fis);
        e = (Employee) in.readObject();
        in.close();

        System.out.println(e.toString());
    }
}
Patrick
  • 1,717
  • 7
  • 21
  • 28
Yasir Shabbir Choudhary
  • 2,458
  • 2
  • 27
  • 31
0

The problem here not in "implements Serializable". The problem is that object not converted in the DBObject.

Possible solution:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.*;

....

ObjectMapper mapper = new ObjectMapper();
DBObject dboJack = mapper.convertValue(new Person("Jack"), BasicDBObject.class);
...
Andrew
  • 36,676
  • 11
  • 141
  • 113
0

You can achieve this by using following code:

import com.google.gson.annotations.Expose;
import com.mongodb.ReflectionDBObject;

class PersonList extends ReflectionDBObject {
    // person property
    @Expose public java.util.List<Person> person;
}

Now in your mongodb code, you can serialise a Person list as follows

....
PersonList personList = new PersonList();
personList.person = new ArrayList<>();
// add persons to the list
....
....
record.put("personsList", personList);
....
// rest of your code
Gaurav Sharma
  • 1,983
  • 18
  • 18
0

class Person should implement java.io.Serializable interface.

class Person implements Serializable

Gaurav
  • 1,549
  • 2
  • 15
  • 31
0

Your Person class definition needs to have implements Serializable in order for it to be serialized, e.g.:

class Person implements Serializable {
   //Rest here
}

Here are some useful links on Java object serialization: Link, Link.

Deco
  • 3,261
  • 17
  • 25
-1

First of all you should know why you make class Serializable? Whenever you want to move obeject on network to a file, database, network, process or any other system. In java simple Implementation. Just Implement Serializable interface.