Entity Aggregates and database Ids

Hi

Ive have applying event sourcing to one of our existing entities/table called User.class.
I am using version 2.0-SNAPSHOT as I prefer the way you can customize the aggregate id

For this User I have two identifiers

public class User extends AbstractAnnotatedAggregateRoot
{
@Id
private String id;

@Column(name = “AGGREGATE_ID”)
@AggregateIdentifier
private UUID identifier;

public User(UserCreatedEvent createdEvent)
{
apply(createdEvent);
}
@EventHandler
protected void handleCreateUser(UserCreatedEvent createdEvent)
{
// Set up defaults
// Code ommitted
}

}

I also have listener to save to the query repository

public class UsersTableUpdater
{
private UserRepository userRepository;

private Repository repository;

@EventHandler
public void handleSave(AbstractUserSavedEvent savedEvent)
{
User user = repository.load(savedEvent.getIdentifier());
userRepository.save(user); // Do a merge or persist depending on whether its new or existing
}
}

When saving an entity for the first time this is fine, however when updating an existing User. My loaded User aggregate does not have my user.id or user.version (inherited from AbstractAnnotatedAggregateRoot) populated.
Because my none of my events doesn’t set values before persisting.
This causes OptimisticLocking and duplicate entity problems for me.

So my question is. What is the best way to keep the version and my primary key id, in sync in the event store. (considering I cannot set the version variable in AbstractAnnotatedAggregateRoot)

Thanks for your help. Hope my explanation was clear.

Richard

Hi Richard,

it looks like you’re storing an Aggregate in the query tables. I’ve never tried to do that. And to be honest, I don’t think it is a good idea. The whole purpose of CQRS is having separate models for commands and queries. The version attribute is set by Axon when events are applied.

In terms of Events, it is important to define them using functional terms. UserSavedEvent is technical. It doesn’t really say what happened. Examples are “UserPersonalDetailsUpdatedEvent”, “UserCreatedEvent” or “UserPasswordChanged”. You event handlers would then update their own model using these events.

Hope this helps you in the right direction.
Cheers,

Allard

I have re-visited the address book example, I think im missing equivalant of the ContactEntry class.

Thanks for your help

Hi Richard,

you might want to take a look at the Trader Sample as well ( https://github.com/AxonFramework/Axon-trader ). It contains a bit more feaures.
Of course, the best alternative is to join the training or workshop that Orange11 (http://www.orange11.nl/en/home/services/training.html) organizes. Modelling is extensively covered in both. There aren’t any trainings planned yet, but if you’re interested, just drop a note.

Cheers,

Allard

I’ll be interested if there it’s in NYC.

Hi,

a training or workshop in NYC is absolutely possible. Typically, we look for co-organizers/hosts that can arrange for the required number of attendees (10-20). If you’re interested in joining or co-organizing, drop me a note.

Cheers,

Allard