Chapter 3. Serialization

Table of Contents

3.1. Data Serializable
3.2. Portable Serialization
3.3. Custom Serialization

All your distributed objects such as your key and value objects, objects you offer into distributed queue and your distributed callable/runnable objects have to beSerializable.

Hazelcast serializes all your objects into an instance ofcom.hazelcast.nio.serialization.Data. Data is the binary representation of an object. When Hazelcast serializes an object intoData, it first checks whether the object is an instance of com.hazelcast.nio.serialization.DataSerializable, if not it checks if it is an instance of com.hazelcast.nio.serialization.Portable and serializes it accordingly. For the following types Hazelcast optimizes the serialization a user can not override this behaviour. Byte, Boolean, Character, Short, Integer, Long, Float, Double, byte[], char[], short[], int[], long[], float[], double[], String, Hazelcast also optimizes the following types, however you can override them by creating a custom serializer and registering it. See Custom Serialization for more information.

Not that if the object is not instance of any explicit type, Hazelcast uses Java Serialization for Serializable and Externalizable objects. The default behaviour can be changed using a Custom Serialization.

3.1. Data Serializable

For a faster serialization of objects, Hazelcast recommends to implement com.hazelcast.nio.serialization.IdentifiedDataSerializable which is slightly better version of com.hazelcast.nio.serialization.DataSerializable.

Here is an example of a class implementing com.hazelcast.nio.serialization.DataSerializable interface.

public class Address implements com.hazelcast.nio.serialization.DataSerializable {
    private String street;
    private int zipCode;
    private String city;
    private String state;

    public Address() {}

    //getters setters..

    public void writeData(ObjectDataOutput out) throws IOException {
        out.writeUTF(street);
        out.writeInt(zipCode);
        out.writeUTF(city);
        out.writeUTF(state);
    }

    public void readData(ObjectDataInput in) throws IOException {
        street    = in.readUTF();
        zipCode = in.readInt();
        city    = in.readUTF();
        state    = in.readUTF();
    }
}

Lets take a look at another example which is encapsulating a DataSerializable field.

public class Employee implements com.hazelcast.nio.serialization.DataSerializable {
    private String firstName;
    private String lastName;
    private int age;
    private double salary;
    private Address address; //address itself is DataSerializable

    public Employee() {}

    //getters setters..

    public void writeData(ObjectDataOutput out) throws IOException {
        out.writeUTF(firstName);
        out.writeUTF(lastName);
        out.writeInt(age);
        out.writeDouble (salary);
        address.writeData (out);
    }

    public void readData (ObjectDataInput in) throws IOException {
        firstName = in.readUTF();
        lastName  = in.readUTF();
        age       = in.readInt();
        salary       = in.readDouble();
        address   = new Address();
        // since Address is DataSerializable let it read its own internal state
        address.readData (in);
    }
}

As you can see, since address field itself isDataSerializable, it is calling address.writeData(out) when writing and address.readData(in) when reading. Also note that the order of writing and reading fields should be the same. While Hazelcast serializes a DataSerializable it writes the className first and when de-serializes it, className is used to instantiate the object using reflection. IdentifiedDataSerializable To avoid the reflection and long class names IdentifiedDataSerializable can be used instead ofDataSerializable. Note that IdentifiedDataSerializable extends DataSerializable and introduces two new methods.

  • int getId();
  • int getFactoryId();

IdentifiedDataSerializable uses getId() instead of className and uses getFactoryId() to load the class given the Id. To complete the implementation a com.hazelcast.nio.serialization.DataSerializableFactory should also be implemented and registered into SerializationConfig which can be accessed from Config.getSerializationConfig(). The Factories responsibility is to return an instance of the right IdentifiedDataSerializable object, given the id. So far this is the most efficient way of Serialization that Hazelcast supports of the shelf.