Questions about @CommandHandler on the AxonBank project

Hello everyone,

I’m new to Axon. I watched the getting started videos and I’m going through the AxonBank project.
In the videos and firsts commits of the project, the CreateBankAccountCommand handler looks like:

@AggregateRoot
public class BankAccount {

    @AggregateIdentifier
    private String id;
    private long overdraftLimit;
    private long balanceInCents;

    @SuppressWarnings("unused")
    private BankAccount() {
    }

    @CommandHandler
    public BankAccount(CreateBankAccountCommand command) {
        apply(new BankAccountCreatedEvent(command.getBankAccountId(), command.getOverdraftLimit()));
    }

Later on, the same command is handled slightly differently, using a repository:

public class BankAccountCommandHandler {

    private Repository<BankAccount> repository;
    private EventBus eventBus;

    public BankAccountCommandHandler(Repository<BankAccount> repository, EventBus eventBus) {
        this.repository = repository;
        this.eventBus = eventBus;
    }

    @CommandHandler
    public void handle(CreateBankAccountCommand command) throws Exception {
        repository.newInstance(() -> new BankAccount(command.getBankAccountId(), command.getOverdraftLimit()));
    }

@Aggregate
public class BankAccount {

    @AggregateIdentifier
    private String id;
    private long overdraftLimit;
    private long balanceInCents;

    @SuppressWarnings("unused")
    private BankAccount() {
    }

    public BankAccount(String bankAccountId, long overdraftLimit) {
        apply(new BankAccountCreatedEvent(bankAccountId, overdraftLimit));

}

My questions are:

  1. What’s the difference between the 2 approaches?
  2. Is the second one the new recommended way?
  3. Is this documented somewhere? (I couldn’t find it on the reference guide)

Thanks.

Luiz Signorelli

Hi Luiz,

Hoping to supply you with some answers here :slight_smile:

  1. The first calls the constructor of the Aggregate through a command message, by annotating the aggregates constructors with @CommandHandler. The latter is a command handling service which creates a new aggregate instance itself and adds it as a new instances into the aggregate repository. Internally, Axon will do a similar ‘newInstance()’ call when you instantiate an aggregate through a @CommandHandler annotated constructor.
  2. I’d say it depends on what you need. Personally I’ve always used option one, thus a @CommandHandler annotated constructor, to create aggregates, which always worked out fine.
  3. I don’t believe it is, because I the usual approach is creation through the aggregate.

I do have to say it’s some time ago I’ve watched the webinars, so I cannot recall why he gave the service example.
Does he say anything specific about it? If not I’d say it just posses as an example of how you could also create an Axon aggregate.

Hope this was helpful.

Cheers,
Steven

Hi Luiz,

check out the reference guide for more details regarding Command Handlers on the Aggregate directly (https://docs.axonframework.org/part2/command-model.html#handling-commands-in-an-aggregate) or on components (https://docs.axonframework.org/part2/command-model.html#external-command-handlers)

Cheers,

Allard