Ejemplo Básico de Persistencia con Java
A veces puede que necesitemos sacar nuestros objetos fuera de la RAM para luego volver a utilizarlos y no perder la información. En lugar de guardar la información del objeto a un archivo y luego volver a instanciar el objeto y repoblarlo con la información guardada, podemos guardar el objeto en sí. A esto en java se conoce como persistencia.
Con java hay muchas maneras de tratar con la persistencia. Hay frameworks que nos pueden facilitar la tarea como por ejemplo Hibernate, Toplink, etc. En este ejemplo se usa la Java Basic Input/Output API contenida en el java.io package.
En java cuando un serializamos un objecto tenemos la garantía de que vamos a poder reconstruirlo después, (ej. queremos grabarlo en un archivo o enviarlo a través de un socket). Para poder serializar un objeto es necesario implementar la interfaz Serializable. Todos los campos del objeto marcados con la palabra transient no se serializarán.
En este ejemplo se cubren los siguientes temas:
- Grabar un objeto a un archivo
- Recuperar el objeto desde archivo.
- Uso de la palabra clave de java Transient.
- Uso del interfaz serializable.
- Uso del serialVersionUID
import java.io.*; public class SerializationDemo { public static void main(String args[]) { // Serialización de Objeto try { //crea el objecto e imprime sus valores por consola MyPojo object1 = new MyPojo("Hello Persisted Object!", -33, 2.72); System.out.println("object1: " + object1); //crea un fichero para persistir el objeto FileOutputStream fos = new FileOutputStream("persisted-object.file"); ObjectOutputStream oos = new ObjectOutputStream(fos); //escribe el objeto serializado a un archivo oos.writeObject(object1); oos.flush(); oos.close(); } catch (Exception e) { System.out.println("Exception during serialization: " + e); System.exit(0); } // Deserialización de objeto try { MyPojo object2; //abre el archivo FileInputStream fis = new FileInputStream("persisted-object.file"); ObjectInputStream ois = new ObjectInputStream(fis); //lee el objeto del archivo object2 = (MyPojo) ois.readObject(); ois.close(); //imprime los valores del objeto persistido System.out.println("object2: " + object2); System.out.println("object2 mystring: " +object2.getMyString()); //saca por pantalla null porque myTransString está marcado como transient System.out.println("object2 mystring2: " +object2.getMyTransString()); } catch (Exception e) { System.out.println("Exception during deserialization: " + e); System.exit(0); } } } //Pojo serializado class MyPojo implements Serializable { public MyPojo(String mystring, int intVal1, double doubleVal) { this.myString = mystring; this.intVal1 = intVal1; this.doubleVal = doubleVal; this.myTransString = "Este valor no se persistirá."; } //safety ID private static final long serialVersionUID = 1234233342333L; //campos para persistir private String myString; private int intVal1; private double doubleVal; //campos que no serán persistidos private transient String myTransString; //getters y 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; } //para sacar todos los valores persistibles por pantalla @Override public String toString() { return "mystring=" + myString + "; intVal1=" + intVal1 + "; doubleVal=" + doubleVal; } }
Ejecutar la aplicación
*myString2 es null porque se ha marcado como transient.
MyPojo
- Es un POJO (Plain Old Java Object) serializado cuyos campos que no sean transient podrán están serializados.
- myTransString está marcado como transient lo que hace que no sea serializado y por lo tanto no será persistido.
- serialVersionUID es un campo de tipo Long de seguridad. Si intentas reconstruir el mismo objeto con un UID diferente saltará una excepción del tipo java.io.InvalidClassException. Esto es útil en caso de que estés compartiendo un objeto entre diferentes aplicaciones, entornos, etc. Si cambias el serialVersionUID cuando cambias el objecto serializado te aseguras de que todos tengan la misma versión.
SerializationDemo class
- La primera parte crea el fichero y guarda el objeto serializado.
- La segunda parte deserializa el objeto e imprime sus valores por pantalla.
persisted-object.file
- Archivo usado para guardar el objecto serializado (persistir). No se guardan los campos marcados como transient.
Notas
- Una vez que está guardado ya no necesitas la primera parte del SerializationDemo.
- Si borras la implementacion de la interface Serializable se lanzará una excepción java.io.NotSerializableException