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

Я работаю над проектом javaFx, где мы должны использовать ObservableList для добавления Listners. ObservableList включает Модель лиц. Но я хочу сохранить весь объект ObservableList в файле посредством сериализации. Но это выдает мне исключение. Я также внедрил сериализацию в объектную модель, но не повезло. Есть ли способ сериализовать ObservableList?

Модель сотрудника

package com.company.Model;

import javax.persistence.*;
import java.io.Serializable;

/**
 * Created by Sunny on 1/8/2016.
 */
@Entity
@Table(name = "Employee", schema = "", catalog = "PUBLIC")
public class EmployeeEntity implements Serializable {
    private String empId;
    private String empAddress;
    private String empNumber;
    private String empFirstName;
    private String empLastName;

    public EmployeeEntity(String empId, String empAddress, String empNumber, String empFirstName, String empLastName) {
        this.empId = empId;
        this.empAddress = empAddress;
        this.empNumber = empNumber;
        this.empFirstName = empFirstName;
        this.empLastName = empLastName;
    }

    public EmployeeEntity() {

    }

    @Id
    @Column(name = "emp_ID")
    public String getEmpId() {
        return empId;
    }

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

    @Basic
    @Column(name = "emp_address")
    public String getEmpAddress() {
        return empAddress;
    }

    public void setEmpAddress(String empAddress) {
        this.empAddress = empAddress;
    }

    @Basic
    @Column(name = "emp_number")
    public String getEmpNumber() {
        return empNumber;
    }

    public void setEmpNumber(String empNumber) {
        this.empNumber = empNumber;
    }

    @Basic
    @Column(name = "emp_firstName")
    public String getEmpFirstName() {
        return empFirstName;
    }

    public void setEmpFirstName(String empFirstName) {
        this.empFirstName = empFirstName;
    }

    @Basic
    @Column(name = "emp_lastName")
    public String getEmpLastName() {
        return empLastName;
    }

    public void setEmpLastName(String empLastName) {
        this.empLastName = empLastName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        EmployeeEntity that = (EmployeeEntity) o;

        if (empId != null ? !empId.equals(that.empId) : that.empId != null) return false;
        if (empAddress != null ? !empAddress.equals(that.empAddress) : that.empAddress != null) return false;
        if (empNumber != null ? !empNumber.equals(that.empNumber) : that.empNumber != null) return false;
        if (empFirstName != null ? !empFirstName.equals(that.empFirstName) : that.empFirstName != null) return false;
        if (empLastName != null ? !empLastName.equals(that.empLastName) : that.empLastName != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = empId != null ? empId.hashCode() : 0;
        result = 31 * result + (empAddress != null ? empAddress.hashCode() : 0);
        result = 31 * result + (empNumber != null ? empNumber.hashCode() : 0);
        result = 31 * result + (empFirstName != null ? empFirstName.hashCode() : 0);
        result = 31 * result + (empLastName != null ? empLastName.hashCode() : 0);
        return result;
    }
}

Сериализация

 public void write(ObservableList<EmployeeEntity> personObservalble) {
        try {
            // write object to file
            FileOutputStream fos = new FileOutputStream("Objectsavefile.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(personsObservable);
            oos.close();


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

Исключение

java.io.NotSerializableException: com.sun.javafx.collections.ObservableListWrapper
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at FileWriter.write(FileWriter.java:14)
    at Main.main(Main.java:12)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Process finished with exit code 0

person Abdullah    schedule 14.01.2016    source источник
comment
Я также внедрил сериализацию в объектную модель, но не повезло. Вы имеете в виду, что добавили implements Serializable в этот класс? Знаете ли вы, что на самом деле это не гарантирует, что экземпляры могут быть сериализованы?   -  person Andy Turner    schedule 14.01.2016
comment
На самом деле я новичок в программировании. поэтому мои представления о сериализации слабы. Теперь я понимаю. сериализация не всегда работает с экземплярами   -  person Abdullah    schedule 14.01.2016
comment
Не могли бы вы попробовать код, который я разместил в ответе, и посмотреть, работает ли он?   -  person James_D    schedule 14.01.2016


Ответы (1)


ObservableList реализации не являются Serializable (по сути, нет разумного способа определить поведение для сериализации слушателей, а вообще не сериализовать слушателей - это то же самое, что сериализовать ненаблюдаемый список с теми же данными, что я думаю, что вы хотите делать здесь.) Предполагая, что ваш класс Person равен Serializable (и что экземпляры действительно могут быть сериализованы), вы можете сделать:

 public void write(ObservableList<EmployeeEntity> personObservalble) {
    try {
        // write object to file
        FileOutputStream fos = new FileOutputStream("Objectsavefile.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(new ArrayList<EmployeeEntity>(personsObservable));
        oos.close();


    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

Чтобы прочитать его обратно, вы должны сделать:

ObjectInputStream ois = ... ;
List<EmployeeEntity> list = (List<EmployeeEntity>) ois.readObject();
personsObservable = FXCollections.observableList(list);

Вот полный тест. Я запустил это, и это сработало (я удалил аннотации постоянства, так как у меня не было javax.persistence в пути к классам в моей тестовой среде, но это не должно иметь значения).

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

public class SerializeObservableListTest {

    public static void main(String[] args) throws IOException {
        EmployeeEntity bill = new EmployeeEntity("1000", "Seattle, WA", "1000", "Bill", "Gates");
        EmployeeEntity tim = new EmployeeEntity("2000", "Mobile, AL", "2000", "Tim", "Cook");

        ObservableList<EmployeeEntity> staff = FXCollections.observableArrayList(bill, tim);

        Path temp = Files.createTempFile("employees", "ser");
        write(staff, temp);

        ObservableList<EmployeeEntity> listFromFile = read(temp);
        System.out.println("Lists equal? "+listFromFile.equals(staff));
    }

    private static void write(ObservableList<EmployeeEntity> employees, Path file) {
        try {

            // write object to file
            OutputStream fos = Files.newOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(new ArrayList<EmployeeEntity>(employees));
            oos.close();


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static ObservableList<EmployeeEntity> read(Path file) {
        try {
            InputStream in = Files.newInputStream(file);
            ObjectInputStream ois = new ObjectInputStream(in);
            List<EmployeeEntity> list = (List<EmployeeEntity>) ois.readObject() ;

            return FXCollections.observableList(list);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return FXCollections.emptyObservableList();
    }
}
person James_D    schedule 14.01.2016
comment
Но вы можете видеть, что у меня есть сериализация на EmployeeModel. все еще я не могу сделать сериализацию. - person Abdullah; 14.01.2016
comment
У меня он работал нормально. Смотрите обновленный ответ. Опубликуйте трассировку стека в своем вопросе, если она действительно не работает с использованием этой техники. - person James_D; 14.01.2016
comment
Но опубликованное вами исключение не использует код, который я написал для вас. - person James_D; 14.01.2016
comment
Это исключение говорит, что вы все еще пытаетесь сериализовать наблюдаемый список. Попробуйте, как я предложил. - person James_D; 14.01.2016
comment
То же исключение сохраняется в основном коде. На самом деле я преобразовал ObservalbleList в ArrayList для сериализации в своем коде... - person Abdullah; 14.01.2016
comment
Серьезно, невозможно получить это исключение, используя код, который я разместил. Просто прочитайте сообщение об ошибке: в нем говорится, что вы сериализуете наблюдаемый список. В строке 14 из FileWriter есть oos.writeObject(new ArrayList<EmployeeEntity>(personsObservable));? - person James_D; 14.01.2016
comment
спасибо за исправление. Я понимаю, что ObservableList нельзя сериализовать. Мы должны преобразовать его в arrayList, а затем сериализовать. После этого мы можем снова скрыть его обратно в ObservableList. - person Abdullah; 14.01.2016
comment
@James_D, если класс содержит ObservableList и реализует serializable, при экспорте объекта этого класса в файл, похоже, не возникает никаких исключений. Почему и каково состояние контента ObservableList? - person ihavenoidea; 27.06.2018