Serialize class for MongoDB model
Asked Answered
B

8

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.

Brittneybrittni answered 5/1, 2012 at 6:17 Comment(2)
how did u do this @vienna.. Plz help me I am having the same problem. Plz helpRepellent
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.Zoe
K
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

Kaffiyeh answered 5/1, 2012 at 6:21 Comment(5)
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; } }Brittneybrittni
@vienna: Did you get the same exception or any other?Kaffiyeh
@vienna: Try adding a default constructor in Person class public Person(){}.Kaffiyeh
@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.Temekatemerity
@vienna: Yes extending BasicDBObject solves problem cause BasicDBObject it self implements Serializable.Kaffiyeh
E
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

Electroballistics answered 6/4, 2015 at 10:43 Comment(0)
H
0

class Person should implement java.io.Serializable interface.

class Person implements Serializable

Hoedown answered 5/1, 2012 at 6:22 Comment(0)
D
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.

Dyak answered 5/1, 2012 at 6:22 Comment(0)
G
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());
    }
}
Gynaeco answered 20/7, 2014 at 8:13 Comment(0)
S
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);
...
Sexdecillion answered 2/1, 2015 at 16:20 Comment(0)
F
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
Faintheart answered 15/3, 2016 at 17:8 Comment(0)
M
-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.

Melodramatic answered 5/1, 2012 at 6:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.