Article updated on

Basic Example of Persistence with Java

Sometimes we may need to save our objects out of the RAM scope. The act of storing  objects outside the RAM is called persistence.

With Java there are many ways of dealing with object persistence and  and many frameworks that allow you to do this easily such us Hibernate, Toplink, etc.. In this example is used the Java Basic Input/Output API which is contained in the java.io package.

In java when an object is serialized we have guarantee that we can reconstruct that object later. (ex. we save it in a file, we send it through a socket, etc.). To serialize an object in java is necessary implement the interface Serializable. If our object implements the interface Serializable but we don't want to persist an specific variable the keyword transient is used.

In the following example the following features are covered.

  • Storing an object into a file.
  • Recovering the object from a file.
  • Use of the java transient keyword.
  • Use of the interface serializable.
  • Use of the serialVersionUID
import java.io.*;
public class SerializationDemo {
    public static void main(String args[]) {
        // Object serialization
        try {
            //creates an object and prints it
            MyPojo object1 = new MyPojo("Hello Persisted Object!", -33, 2.72);
            System.out.println("object1: " + object1);
            //creates a file to persist the object
            FileOutputStream fos = new FileOutputStream("persisted-object.file");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            //writes the object to the file
            oos.writeObject(object1);
            oos.flush();
            oos.close();
        } catch (Exception e) {
            System.out.println("Exception during serialization: " + e);
            System.exit(0);
        }
        // Object deserialization
        try {
            MyPojo object2;
            //opens a file
            FileInputStream fis = new FileInputStream("persisted-object.file");
            ObjectInputStream ois = new ObjectInputStream(fis);
            //reads the object from the file
            object2 = (MyPojo) ois.readObject();
            ois.close();
            //prints values from the reconstructed persisted object
            System.out.println("object2: " + object2);
            System.out.println("object2 mystring: " +object2.getMyString());
            //prints null because myTransString is marked as transient
            System.out.println("object2 mystring2: " +object2.getMyTransString());            
        } catch (Exception e) {
            System.out.println("Exception during deserialization: " + e);
            System.exit(0);
        }
    }    
}
//Serialized pojo
class MyPojo implements Serializable {    
    public MyPojo(String mystring, int intVal1, double doubleVal) {
        this.myString = mystring;
        this.intVal1 = intVal1;
        this.doubleVal = doubleVal;
        this.myTransString = "This value is not meant to be persisted.";
    }
    //safety ID
    private static final long serialVersionUID = 1234233342333L;
    //fields meant to be persisted
    private String myString;
    private int intVal1;
    private double doubleVal;    
    //fields not meant to be persisted
    private transient String myTransString;
    //getters and setters
    public String getMyString() {
        return myString;
    }
    public void setMyString(String myString) {
        this.myString = myString;
    }
    public String getMyTransString() {
        return myTransString;
    }
    public void setMyTransString(String myTransString) {
        this.myTransString = myTransString;
    }
    public int getIntVal1() {
        return intVal1;
    }
    public void setIntVal1(int intVal1) {
        this.intVal1 = intVal1;
    }
    public double getDoubleVal() {
        return doubleVal;
    }
    public void setDoubleVal(double doubleVal) {
        this.doubleVal = doubleVal;
    }
    //to print all the persisted values
    @Override
    public String toString() {
        return "mystring=" + myString + "; intVal1=" + intVal1 + "; doubleVal=" + doubleVal;
    }
}

Executing the Application

img/0/25/_002.jpeg

*myString2 is null because is marked as transient.

MyPojo

  • It is a serialized Plain Old Java Object whose objects are meant to be persisted except the ones marked as transient. Overrides toString in order to print the output values.
  • myTransString is a transient field that means that it won't be persisted. Remove this keyword if you want to make it persistent.
  • serialVersionUID is for safety. If you are trying to reconstruct a persisted object with a different UID you will get a java.io.InvalidClassException. This is used in case you are sharing an object among different apps, environments etc. They are all meant to have a copy of the same serialized class (in this case MyPojo). With the serialVersionUID you can make sure that all of them have the same version, if they don't they'll get the exception.

SerializationDemo class

  • The first part serializes the object and persists it.
  • Second part deserializes the object and print values from the persisted object.

persisted-object.file

  • File used to persist the object. Once the file is persisted the file will contain the serialized object.

img/0/25/_001.jpeg

Notes

  • Once the object is persisted you can remove the first part of the SerializationDemo.
  • If you remove the Serializable interface implementation you will get a java.io.NotSerializableException