Serialization - hazelcast/hazelcast-scala GitHub Wiki
Built-in
The Scala API provides a set of default serializers for common data types. To enable, register them to the configuration:
serialization.Defaults.register(conf.getSerializationConfig)
Custom
The Hazelcast Java API provides two type-class interfaces for serialization, ByteArraySerializer
and StreamSerializer
. Both extend a common Serializer
interface that requires a unique getTypeId()
.
In the Scala API this can be automated by encapsulating the serializers in an Enumeration
container SerializerEnum
, which removes the need for a separate place to track such ids.
Given an Employee
class:
case class Employee(id: UUID, name: String)
The serializer implementation, inside the SerializerEnum
container, would look like this:
import com.hazelcast.nio.{ObjectDataOutput, ObjectDataInput}
import java.util.UUID
object MySerializers extends SerializerEnum {
val EmployeeSer = new StreamSerializer[Employee] {
def write(out: ObjectDataOutput, emp: Employee): Unit = {
out.writeLong(emp.uuid.getMostSignificantBits)
out.writeLong(emp.uuid.getLeastSignificantBits)
out.writeUTF(emp.name)
}
def read(inp: ObjectDataInput): Employee = {
val id = new UUID(inp.readLong, inp.readLong)
val name = inp.readUTF()
Employee(id, name)
}
}
}
Like the default serializers, they must be registered:
MySerializers.register(conf.getSerializationConfig)
Serialization libraries
The SerializerEnum
can also be leveraged to further minimize boilerplate, by using one of the many serialization libraries available.
E.g. to use the BooPickle library, you can easily write a general BooPickle container:
import java.nio.ByteBuffer
import scala.reflect.ClassTag
import com.hazelcast.Scala.serialization.SerializerEnum
import boopickle.Default._
class BooPicklers extends SerializerEnum {
class BooPickle[T: Pickler: ClassTag] extends ByteArraySerializer[T] {
def write(t: T): Array[Byte] = {
val bb = Pickle.intoBytes(t)
val bytes = new Array[Byte](bb.remaining)
bb.get(bytes)
bytes
}
def read(bytes: Array[Byte]): T = {
val bb = ByteBuffer.wrap(bytes)
Unpickle[T].fromBytes(bb)
}
}
}
With that, you can add your serializers without writing serialization code:
import boopickle.Default._
object MyPicklers extends BooPicklers {
val EmployeeSer = new BooPickle[Employee]
}
Again, must be registered:
MyPicklers.register(conf.getSerializationConfig)