как сериализовать класс?

Когда я вставляю список в mongodb, возникает проблема:

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)

класс Person определяется следующим образом:

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

Программа:

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

Я не могу найти ответ в Google, поэтому, пожалуйста, помогите мне.


person NOrder    schedule 05.01.2012    source источник
comment
как ты это сделал @vienna .. Пожалуйста, помогите мне, у меня такая же проблема. Пожалуйста, помогите   -  person shalki    schedule 22.06.2012
comment
Наблюдение: одним из преимуществ MongoDB является возможность изменять схему с течением времени без необходимости обновлять существующие документы с помощью этих новых полей. Поэтому вы можете хранить свои объекты как документы (т.е. с полем для имени и т. д.), или если вы действительно хотите выполнить двоичную сериализацию, вы можете предпочесть использовать что-то вроде Google Protocol Buffers, который является более перспективным. способ достижения двоичной сериализации.   -  person Rich    schedule 21.08.2013


Ответы (8)


Просто реализуйте интерфейс Serializable в классе Person.

Также было бы хорошо определить serialVersionUID в вашем классе.

Насколько мне известно, при создании класса POJO в java класс должен быть сериализуемым, если он будет передаваться по какому-либо потоку, иметь конструктор по умолчанию и разрешать доступ к свойствам/полям с использованием методов получения и установки.

Возможно, вам будет интересно прочитать это: Откройте для себя секреты Java Serialization API

person Harry Joy    schedule 05.01.2012
comment
Но у меня все еще есть проблема, хотя я реализую интерфейс Serializable; класс Person реализует Serializable{ private String name; общественное лицо (имя строки) { this.name = имя; } public String getName() { возвращаемое имя; } public void setName(String name) { this.name = name; } } - person NOrder; 05.01.2012
comment
@vienna: Вы получили такое же исключение или любое другое? - person Harry Joy; 05.01.2012
comment
@vienna: попробуйте добавить конструктор по умолчанию в класс Person public Person(){}. - person Harry Joy; 05.01.2012
comment
@vienna, это потому, что у вас есть только 1 конструктор, и он принимает аргумент. Класс POJO не может иметь аргументов или конструктор аргументов, отсчитываемый от нуля. Я предлагаю сделать то, что Гарри Джой сказал выше. - person Buhake Sindi; 05.01.2012
comment
@vienna: Да, расширение BasicDBObject решает проблему, потому что BasicDBObject сам реализует сериализуемый. - person Harry Joy; 05.01.2012

У меня такое же исключение при работе с mongodb. Я попытался сделать проблемный класс сериализуемым, но это не решило мою проблему.

Ниже приведено то, что сработало для меня. Расширьте класс, чтобы он был дочерним по отношению к BasicDBObject . Конечно, это работает, только если проблема вызвана MongoDB.

extends BasicDBObject 

Первоисточник

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

person Pratik Patel    schedule 06.04.2015

класс Person должен реализовать интерфейс java.io.Serializable.

class Person implements Serializable

person Gaurav    schedule 05.01.2012

Ваше определение класса Person должно иметь implements Serializable, чтобы его можно было сериализовать, например:

class Person implements Serializable {
   //Rest here
}

Вот несколько полезных ссылок по сериализации объектов Java: Ссылка, Ссылка.

person Deco    schedule 05.01.2012

Проблема тут не в "реализует Serializable". Проблема в том, что объект не конвертируется в DBObject.

Возможное решение:

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

....

ObjectMapper mapper = new ObjectMapper();
DBObject dboJack = mapper.convertValue(new Person("Jack"), BasicDBObject.class);
...
person Andrew    schedule 02.01.2015

Вы можете добиться этого, используя следующий код:

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

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

Теперь в вашем коде mongodb вы можете сериализовать список лиц следующим образом.

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

Вот пример кода для сериализации объекта Employee:

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());
    }
}
person Yasir Shabbir Choudhary    schedule 20.07.2014

Прежде всего, вы должны знать, почему вы делаете класс Serializable? Всякий раз, когда вы хотите переместить объект по сети в файл, базу данных, сеть, процесс или любую другую систему. В java простая реализация. Просто реализуйте сериализуемый интерфейс.

person Community    schedule 05.01.2012