1

I have a StorageImpl class which is serializable. This class has an inner class Record.

public class StorageImpl <ID, T extends IDataStore<ID>> implements IStorage <T, ID>
{

    private class Record implements Serializable
    {
        private static final long serialVersionUID = 1L;

        private Long key;
        private List<T> dataList;

        private Record()
        {
            key      = new Long(0);
            dataList = new ArrayList<T>();
        }
    }
}

I want to store and retrieve a Record which in turn has

private Long key;
private List<T> dataList;

Once I retrieve a Record, I can get all the books in bookList member of the Record.

public class StorageImpl <ID, T extends IDataStore<ID>> implements IStorage <T, ID>
{
    private class Record implements Serializable
    {
        private static final long serialVersionUID = 1L;

        private Long key;
        private List<T> dataList;

        private Record()
        {
            key      = new Long(0);
            dataList = new ArrayList<T>();
        }

    private String dataFile;
    private Record record;

    public StorageImpl(String dataFile)
    {
        this.dataFile = dataFile;
        record        = new Record();
    }


    public List<T> retrieve() throws Exception
    {
        List<T> dataList = new ArrayList<>();

        File file = new File(dataFile);

        if (!file.exists())
        {
            return dataList;
        }        

        try (FileInputStream fis = new FileInputStream(dataFile); ObjectInputStream ois = new ObjectInputStream(fis))
        {
            record = (Record) ois.readObject();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }

        for (int i = 0; i < record.dataList.size(); i++) 
        {
            dataList.add(record.dataList.get(i));
        }

        return dataList;
    }
    @SuppressWarnings("unchecked")
    @Override
    public void store(T t) throws Exception
    {
       List<T> dataList = retrieve();

       ++record.key;        
       t.setID((ID) record.key);
       dataList.add(t);

       record.dataList = dataList;
               writeData(record);
    }
    private void writeData(Record record)
    {
        try (FileOutputStream fos = new FileOutputStream(dataFile);
             ObjectOutputStream oos = new ObjectOutputStream(fos))
        {
            oos.writeObject(record);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

Update:

Please note I want to persist just a Record and not a List.

The error after code changes looks like relates to Record not being serializable:

Caused by: java.io.NotSerializableException:

atjava.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at StorageImpl.writeData(StorageImpl..java:159)

And this is the call inside writeData() at line 159

oos.writeObject(record);
0

1 Answer 1

1

It looks like you're reading the whole list from the file, but casting it to be a single Record.

To load an ArrayList containing Record objects you need Record to be serializable, but you're still loading the entire ArrayList, so the cast is incorrect (i.e. you can just store the result directly into recordList).

List<Record> recordList = new  ArrayList<>();

try (FileInputStream fis = new FileInputStream(dataFile); ObjectInputStream ois = new ObjectInputStream(fis))
{
    recordList = (List<Record>) ois.readObject();
}
catch (IOException e)
{
    e.printStackTrace();
}
catch (ClassNotFoundException e)
{
    e.printStackTrace();
}
Sign up to request clarification or add additional context in comments.

8 Comments

But I do not want to persist or read a list of records List<Record>. I want to persist or read just a Record which in turn has a key and a list of all the books in this case. Once I retrieve a Record, I can get all the books in bookList member of the Record. I will update my question.
Ah, okay. I think the core of the problem is still the same, in that you have stored a list. So if the expected behavior is that you should read a record, then the problem is probably with your store call, because that is, i'm guessing, still storing just the list.
Thank you. As per your feedback, I have updated my question with more details. If you get a chance to review it again, that would be highly appreciated.
That looks like it should run to me. Make sure you've not got a left-over file from the previous version (i.e. one that i storing an array and not a record).
I can get the code to run if you extract the Record (i.e. put it in it's own file, not as an inner class). I think there are issues with seriaizability and inner classes.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.