Hi Everyone,
Yesterday I thought I replied to this thread, but it seems that I did not. Thanks a lot for your feedback so far.
My goal is to merge Domain Object A with Domain Object B and keep Domain Object A and delete Domain Object B. I tried the following approach (based on Allard’s feedback):
- Read all events that were sent to Domain Object B
- Converted each event into commands targetted to Domain Object A
- Executed these commands (using the command gateway)
This approach worked better than anticipated as all event handlers and sagas were triggered during the process. Unfortunately, I am not convinced yet and would like to get your views as I believe that this is can be done in a better way. What I have learnt so far about the Axon Framework is that if you are writing boilerplate code, then you are doing it wrong.
As mentioned above, I had to convert the events targetted to Domain Object B into commands targetted to Domain Object A. My first (ugly) approach was to read all events for Domain Object B and convert them to commands targetted to Domain Object A using a ladder of if/else statements as shown next.
final Object payload = message.getPayload();
if (payload instanceof AbcEvent) {
/* Convert event to commands and send them */
}
if (payload instanceof DefEvent) {
/* Convert event to commands and send them */
}
/* Do this for all events of interest */
The approach shown above has two issues:
- This can get long quickly as we need a new condition for every event
- We are replaying all events even the old ones which have been replaced by other new events
Another approach is to use polymorphism where the events themselves will implement an interface, such as
public interface ToCommandsConvertable {
List toCommands(T targetIdentifier);
}
and then each event will be responsible for converting itself into a command targetted to another aggregate by implementing the above method.
I prefer the second option (use polymorphism) as it improves the code cohesion and mitigates the issue of forgetting an event out. But this only addresses the first problem.
The second problem can be addressed by using a new (stateful) class, similar to the responsible aggregate, that plays all events, digests them, and then triggers the minimum number of commands. In other words, this class state is modified while playing the Domain Object B events, and then once it plays all events of interest, it triggers the minimum number of commands targetted to Domain Object A.
As already mentioned, this seems to involve lots of boilerplate code and I want to double check before adopting this approach.
Any feedback is more than welcome.