Each aggregate publishes one or more events. Events represent important things that occur to an aggregate. Some events represent a state change and ensure an aggregate is persisted. Events can also represent attempts to violate business rules. You must define a Java class for each event type.
Each event class must specify the aggregate class that publishes the event.
You do this using the @EventEntity
annotation, which specifies the entity class name rather than the class object.
That’s because the query side also uses these event classes, but entity class is not available on the query side.
One way to specify the aggregate type is by annotating the package that contains the event class:
@net.chrisrichardson.eventstore.EventEntity(entity="net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts.Account")
package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts;
The other way to specify the aggregate type is to annotate either the event class or one of its superclasses or superinterfaces. An easy way to do this is to define and annotate a superinterface for each aggregate:
@EventEntity(entity="net.chrisrichardson.eventstore.examples.customersandorders.order.Order")
public interface OrderEvent extends Event {
}
The aggregate’s event classes then implement this interface.
public class OrderCreatedEvent implements OrderEvent {
...
}
There is no need to include metadata in your event. An event class defines fields the aggregate’s business logic needs. It can also define all fields the consumer of the event requires; this is the concept of event enrichment.
Remember that consumers have access to certain metadata (the event ID and the type and ID of the entity that publishes the event) via the event handler API. Consequently, you don’t need to define fields for this data in your event classes.
Sometimes, an event class can define equals()
and hashCode()
methods, making it simpler to write tests that make assertions about expected events.
Events must be serializable to and from JSON. The Java Eventuate Client currently uses the Jackson JSON library. Unfortunately, as of the time of writing it does not expose a way to customize it’s ObjectMapper. This will change in a future release.