Checking if a user aggregate exists by email address

I’m trying to implement a simple CRUD User API and am wondering how to perform certain validations in the user aggregate.

For instance, when a new user is created, the email address must be unique. Thus, I’m trying to first check if an aggregate containing the new email address already exists before sending my UserCreatedEvent. Is this the right way to do this or am I missing something?

    @CommandHandler
    public UserAggregate(final CreateUserCommandImpl command) {

        // Check if user already exists

        AggregateLifecycle.apply(UserCreatedEventImpl
                .builder()
                .id(command.getId())
                .email(command.getEmail())
                .firstName(command.getFirstName())
                .lastName(command.getLastName())
                .build());
    }

Hi @jackson.korba,

This is possible and something we call Set Based Validation!
You can have a look at this blog here where it will explain the problem and also onw way to solve it =)

KR,

Thanks for the response!

Given the article you sent, it appears what I would want to do is to add a dispatch interceptor which will verify that the email address doesn’t already exist before any aggregate is loaded and before an event is published. It seems like there is an opportunity for a race condition here…

Querying to check if an email exists occurs before a user event is published, and updating the email lookup table occurs after a user event is published. Couldn’t the email exists query pass for two concurrent CreateUserCommand’s, resulting in two UserCreatedEvent’s firing with the same email? Usually this validation is atomic by simply relying on a uniqueness constraint in the database.

Any help is appreciated!

Hi @jackson.korba,

Indeed there can be a small race condition there, which could be covered by the changes made on this PR.

But, if you ask me, the opportunity window is so small that depending on your use case, it is not worth.
Granted that, this is a Command Side Projection and it is updated right away (using a subscribing processor), so pretty much synchronous with your Command Handling!

There is no such thing as “uniqueness constraint” when dealing with Events, that’s why a Set Based Validation is generally used, this is your uniqueness constraint =)

KR,