EventStore.Akka.Persistence JSON serialization using Jackson (JAVA)

We’ve ended up with following serializer for Event Store persistence:

import akka.persistence.PersistentImpl;

import akka.persistence.PersistentRepr;

import akka.persistence.eventstore.EventStoreSerializer;

import org.ad.domain.CampaignCreated;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import eventstore.Event;

import eventstore.EventData;

import eventstore.j.EventDataBuilder;

import scala.Option;

import java.io.IOException;

import static akka.actor.ActorRef.noSender;

public class JsonSerializer implements EventStoreSerializer {

@Override

public int identifier() {

return 10023;

}

@Override

public byte[] toBinary(Object o) {

ObjectMapper mapper = new ObjectMapper();

try {

String s = mapper.writeValueAsString(o);

return s.getBytes();

} catch (JsonProcessingException e) {

e.printStackTrace();

}

return null;

}

@Override

public boolean includeManifest() {

return true;

}

@Override

public Object fromBinary(byte[] bytes, Option<Class<?>> classOption) {

return fromBinary(bytes, classOption.get());

}

@Override

public Object fromBinary(byte[] bytes) {

return null;

}

@Override

public Object fromBinary(byte[] bytes, Class<?> aClass) {

ObjectMapper mapper = new ObjectMapper();

try {

return mapper.readValue(bytes, aClass);

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

@Override

public EventData toEvent(Object o) {

PersistentImpl obj = (PersistentImpl) o;

EventDataBuilder eventDataBuilder = new EventDataBuilder(obj.payload().getClass().getName());

eventDataBuilder.jsonData(new String(toBinary(obj.payload())));

eventDataBuilder.jsonMetadata(obj.payload().getClass().getName());

return eventDataBuilder.build();

}

@Override

public Object fromEvent(Event event, Class<?> aClass) {

Object result = null;

try {

result = fromBinary(event.data().data().value().toArray(), Class.forName(event.data().eventType()));

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

PersistentRepr persistentRepr = new PersistentImpl(

result,

event.number().value(),

event.streamId().value(),

false,

null,

noSender()

);

return persistentRepr;

}

}

``

We have several questions:

  • Method fromBinary(byte[] bytes) always returns null. Is it safe to assume, that it will not ever be called?
  • We are persisting our own objects, but not PersistentRepr. This leads us to recrecreating PersistentRepr each time with dummy parameters. Is it ok? Will we encounter any problems?
    Thank you in advance!

Hi Aleksey,

We’ve ended up with following serializer for Event Store persistence:

import akka.persistence.PersistentImpl;

import akka.persistence.PersistentRepr;

import akka.persistence.eventstore.EventStoreSerializer;

import org.ad.domain.CampaignCreated;

import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import eventstore.Event;

import eventstore.EventData;

import eventstore.j.EventDataBuilder;

import scala.Option;

import java.io.IOException;

import static akka.actor.ActorRef.noSender;

public class JsonSerializer implements EventStoreSerializer {

@Override

public int identifier() {

return 10023;

}

@Override

public byte[] toBinary(Object o) {

ObjectMapper mapper = new ObjectMapper();

try {

String s = mapper.writeValueAsString(o);

return s.getBytes();

} catch (JsonProcessingException e) {

e.printStackTrace();

}

return null;

}

@Override

public boolean includeManifest() {

return true;

}

@Override

public Object fromBinary(byte[] bytes, Option<Class<?>> classOption) {

return fromBinary(bytes, classOption.get());

}

@Override

public Object fromBinary(byte[] bytes) {

return null;

}

@Override

public Object fromBinary(byte[] bytes, Class<?> aClass) {

ObjectMapper mapper = new ObjectMapper();

try {

return mapper.readValue(bytes, aClass);

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

@Override

public EventData toEvent(Object o) {

PersistentImpl obj = (PersistentImpl) o;

EventDataBuilder eventDataBuilder = new EventDataBuilder(obj.payload().getClass().getName());

eventDataBuilder.jsonData(new String(toBinary(obj.payload())));

eventDataBuilder.jsonMetadata(obj.payload().getClass().getName());

return eventDataBuilder.build();

}

@Override

public Object fromEvent(Event event, Class<?> aClass) {

Object result = null;

try {

result = fromBinary(event.data().data().value().toArray(), Class.forName(event.data().eventType()));

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

PersistentRepr persistentRepr = new PersistentImpl(

result,

event.number().value(),

event.streamId().value(),

false,

null,

noSender()

);

return persistentRepr;

}

}

``

We have several questions:

  • Method fromBinary(byte[] bytes) always returns null. Is it safe to assume, that it will not ever be called?

Not ok in case you bound it to PersistentRepr in config, as it may be used for akka’s own stuff, better to fallback to default serializer, also it might be useful for tests.

  • We are persisting our own objects, but not PersistentRepr. This leads us to recrecreating PersistentRepr each time with dummy parameters. Is it ok? Will we encounter any problems?

That’s ok, have you seen serialization examples written in Scala? :slight_smile: