Understanding command handling constructor

Hello,

I am currently trying to understand how the command handler (@CommandHandler) works on constructors and its use on aggregate members (@AggregateMember). I read the official documentation, but it’s not enough for me to understand everything.

Question 1 : What is the difference between using the commandHandler annotation on methods and constructors and what is happening behind the scene when Axon handle these cases ? (click to expand the content)
@Aggregate
public class GiftCard {

    @AggregateIdentifier
    private String giftCardId;
    private int remainingValue;

    @CommandHandler // Case A
    public GiftCard(IssueCommand command) {
        apply(new IssuedEvent(command.getId(), command.getAmount()));
    }

    @CommandHandler // Case B
    public void handle(IssueCommand command) {
        apply(new IssuedEvent(command.getId(), command.getAmount()));
    }

    @EventSourcingHandler
    public void on(IssuedEvent event) {
        giftCardId = event.getId();
        remainingValue = event.getAmount();
    }

I’m trying to understand what are the steps that Axon does when it handles these two cases. Based on my (maybe wrong) understanding :

Case A : If an IssueCommand is sent, the constructor will be triggered and an instance will be created (and I don’t know what Axon does with this instance). Then, the EventSourcingHandler will be triggered and at this point the IssuedEvent will be stored.
Case B : If an IssueCommand is sent, the method ‘handle’ will be triggered and the event will be sent, triggering the EventSourcingHandler. And then, the IssuedEvent will be stored.

I don’t find any differences between the two cases. Please correct me if I misunderstood something by showing me the correct steps.



The second question regarding aggregate members heavily depends on the answer of the first question, so I will wait for it. In short, I’m trying to find a proper way to use them, but since I didn’t understand the constructor command handlers (and if we also have to use these handlers on aggregate members), I prefer to have a complete answer on the first question.

Also, if you have some resources or lessons for beginners on axon framework, I’ll be happy to have them please. The only videos I found were too short and only talking about simple apps (no mention of aggregate members or more in-depth aspects with real entreprise applications).

Hi,

In regards to your question on trainings, please check out our events page of our website for more info.
I’m presenting a one-hour webinar tomorrow (Oct. 6th) on DDD, CQRS, and Event Sourcing with Axon if you’re interested.

Also our Academy was recently launched and it contains pretty nice free courses!

2 Likes

Hey @per0xyde, let me try to help you on Q1 :slight_smile:

The difference is to be clear when you want to ‘create’ an Aggregate and when you want to ‘update’ an existing Aggregate.

  • Using a Constructor Command Handler will make sure Axon Framework creates a new Aggregate for you! Usually there is no business logic here, you just create it, you apply an Event which will be handled by your Event Sourcing Handler and after that (not going into UoW here), that Event is stored on your Event Store.

  • Using a Command Handler method, Axon Framework will, based on the @TargetAggregateIdentifier field of your Command, try to load that specific Aggregate before applying the new Command. If you Aggregate does not exist, it will throw an Exception. Also, usually you have business logic in your Command Handler methods in this case.

I would like to add to the second case the AggregateCreationPolicy, which is something new that you can use to annotate your CommandHandler and give it “special powers”. In this example, we would be interested in the @CreationPolicy(AggregateCreationPolicy.CREATE_IF_MISSING) which will tell your method to Create an Aggregate if it can’t find one on your Event Store. Of course this is a costy operation since you will have to look for that Aggregate on your Event Store without knowing if you will find it or not - in that case, I would avoid it and only use if there is a specific use case for that.

Another note, DDD is all about being explicity. So using a constructor to create an Aggregate is the best approach IMO.

KR,

2 Likes

Hello and welcome to the Axon community @per0xyde

I see Lucas has already provided an excellent answer to your question. I just wanted to add a link to a response I wrote to a somewhat related question some time ago: Understanding of @TargetAggregateIdentifier - #2 by milendyankov Perhaps you’ll find the information there helpful too.

3 Likes

Thanks a lot for the explanations @lfgcampos and @milendyankov ! I learned a lot by reading the combination of the two answers.

And thank you @Sara_Torrey for providing me some resources to learn more, I was searching for this.
I’m a student and I must work on a project to validate the degree. I chose to work on Axon framework with Spring and I will have to introduce it to other students and teachers at my university. The academy will help me because I didn’t find complete structured courses yet, only independant videos here and there and some paid courses that I can’t afford (except a great one on udemy by Sergey Kargopolov which has practical exercises on a real project, not just samples).
I’m glad I asked the question and I hope it will be updated continuously with live coding of real projects from A to Z, so we can rely or practice on them. I will share the platform with other students who might be interested, thank you.

2 Likes