1

I have an eventsourced aggregate and use Jackson as eventserializer. Now, when I apply an event A in a command handler, I can see it's event sourcing handler called immediately, with all the expected event fields (event is the same instance as I created in the command handler). One of the fields in the event is the aggregateId.

However, when the (read side) event handler is called, the event object is a different instance, but the field I filled with the aggregateId has a wrong value! Debugging shows it is filled with the event identifier. When I set a breakpoint in the event constructors, I see it called and a wrong field value being set.

When I switch to XStream as event serializer, everything is fine. No additional even instantion is done, and the event created in the command handler is the same as being processing in the eventhandler.

What is going on here?

JointEffort
  • 583
  • 7
  • 21

1 Answers1

4

After an hour of debugging, I found my own mistake ;-). As the Axon docs say, when using Jackson as EventSerializer, you have to stick to the Jackson conventions, which I didn't. All my aggregate id's are subclasses of this AggregateId:

public abstract class AggregateId {

    private final UUID id;

    public AggregateId() {
        this(UUID.randomUUID());
    }

    public AggregateId(UUID id) {
        this.id = id;
    }

    public String toString() {
        return id.toString();
    }

    public UUID getValue() {
        return id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AggregateId that = (AggregateId) o;
        return id.equals(that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

Having a private field id with no getter and a getValue that returns that id is the perfect way to fool Jackson (and myself).

After renaming id to value all tests are green.

JointEffort
  • 583
  • 7
  • 21