@Configuration
public class AxonJavaConfig {
@Bean
EventBus eventBus() {
return new SimpleEventBus();
}
@Bean
public MongoClient mongo() throws UnknownHostException {
return new MongoClient("127.0.0.1", 27017);
}
@Bean
public MongoTemplate mongoSpringTemplate() throws UnknownHostException {
return new MongoTemplate(mongo(), "tribertodo");
}
@Bean
public org.axonframework.mongo.eventsourcing.eventstore.MongoTemplate mongoTemplate() throws UnknownHostException {
return new DefaultMongoTemplate(mongo(), "tribertodo", "domainevents", "snapshotevents");
}
@Bean
public EventStore eventStore() throws UnknownHostException {
return new EmbeddedEventStore(eventStorageEngine());
}
@Bean
public MongoEventStorageEngine eventStorageEngine() throws UnknownHostException {
return new MongoEventStorageEngine(mongoTemplate());
}
@Bean
public Repository<TodoList> todoListCommandRepository() throws UnknownHostException {
return new EventSourcingRepository<TodoList>(TodoList.class, eventStore());
}
@Bean
public TodoListCommandHandler todoListCommandHandler() throws UnknownHostException {
return new TodoListCommandHandler(todoListCommandRepository());
}
}
My aggregate looks like this (written in Kotlin)
@Aggregate
@AggregateRoot
class TodoList {
val logger: Logger = LoggerFactory.getLogger(this.javaClass)
@AggregateIdentifier
var uuid: UUID? = null
constructor()
constructor(uuid: UUID, name: String) {
logger.info("Creating todolist: " + uuid)
AggregateLifecycle.apply(TodoListCreatedEvent(uuid, name))
}
@EventHandler
fun on(event: TodoListCreatedEvent) {
uuid = event.uuid
}
}And the command handler (also in Kotlin):open class TodoListCommandHandler(private val repository: Repository<TodoList>) {
@CommandHandler
open fun on(command: CreateTodoListCommand) {
repository.newInstance { TodoList(command.uuid, command.name) }
}
}So no idea what I am missing, any help appreciated.
open class TodoListCommandHandler(private val repository: Repository<TodoList>) {
@CommandHandler
open fun on(command: CreateTodoListCommand) {
repository.newInstance { TodoList(command.uuid, command.name) }
}
@CommandHandler
open fun on(command: UpdateTodoListNameCommand) {
val aggregate = repository.load(command.uuid.toString())
aggregate.execute { it.updateName(command.uuid, command.name) }
}
}
And the aggregateroot is:
@AggregateRoot
class TodoList {
val logger: Logger = LoggerFactory.getLogger(this.javaClass)
@AggregateIdentifier
var uuid: UUID? = null
constructor()
constructor(uuid: UUID, name: String) {
logger.info("Creating todolist: " + uuid)
AggregateLifecycle.apply(TodoListCreatedEvent(uuid, name))
}
@EventHandler
fun on(event: TodoListCreatedEvent) {
uuid = event.uuid
}
fun updateName(uuid: UUID, name: String) {
logger.info("Updating todolist: " + uuid)
AggregateLifecycle.apply(TodoListNameUpdatedEvent(uuid, name))
}
}I can see that i don't end up in the eventhandler for the creationEvent. I would have expected that that is. So i must be missing a piece?
@EventHandler
fun on(event: TodoListCreatedEvent) {
uuid = event.uuid
}
replace @EventHandler by @EventSourcingHandler and you can create another external class as an EventHandler with @ EventHandler annotation
@Component
class TodoListService @Inject constructor(private val todoListRepository: TodoListRepository) {
val logger: Logger = LoggerFactory.getLogger(TodoListService::class.java)
@EventHandler
fun on(event: TodoListCreatedEvent) {
logger.info("Creatint todolist")
todoListRepository.save(TodoList(event.uuid.toString(), event.name))
}
}
But it fails when i don't have a EventBus like this:
@Bean
public EventBus eventBus() {
return new SimpleEventBus();
}But if i have it i get this warning 'Multiple beans of type EventBus found in application context: [eventBus, eventStore]. Chose eventBus'. But my events are not picked up in the TodoListService.
But even if i remove the eventbus and the service, i still can't get the eventsourcing to work due to 'org.axonframework.eventsourcing.IncompatibleAggregateException: Aggregate identifier must be non-null after applying an event. Make sure the aggregate identifier is initialized at the latest when handling the creation event.'
--
You received this message because you are subscribed to the Google Groups "Axon Framework Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to axonframewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
@Configuration
public class AxonJavaConfig {
@Bean
public MongoClient mongo() throws UnknownHostException {
return new MongoClient("127.0.0.1", 27017);
}
@Bean
public MongoTemplate mongoSpringTemplate() throws UnknownHostException {
return new MongoTemplate(mongo(), "tribertodo");
}
@Bean
public org.axonframework.mongo.eventsourcing.eventstore.MongoTemplate mongoTemplate() throws UnknownHostException {
return new DefaultMongoTemplate(mongo(), "tribertodo", "domainevents", "snapshotevents");
}
@Bean
public MongoEventStorageEngine eventStorageEngine() throws UnknownHostException {
return new MongoEventStorageEngine(new JacksonSerializer(), null, mongoTemplate(), new DocumentPerEventStorageStrategy());
}
}
And the aggregateroot now looks like this:
@AggregateRoot
@Aggregate
class TodoList {
val logger: Logger = LoggerFactory.getLogger(this.javaClass)
@AggregateIdentifier
var uuid: UUID? = null
constructor()
@CommandHandler
constructor(command: CreateTodoListCommand) {
logger.info("Creating todolist: " + command.uuid)
AggregateLifecycle.apply(TodoListCreatedEvent(command.uuid, command.name))
}
@EventSourcingHandler
fun on(event: TodoListCreatedEvent) {
uuid = event.uuid
}
@CommandHandler
fun updateName(command: UpdateTodoListNameCommand) {
logger.info("Updating todolist: " + command.uuid)
AggregateLifecycle.apply(TodoListNameUpdatedEvent(command.uuid, command.name))
}
}When i now issue the CreateTodoListCommand, i can see the command being saved in mongo, so success so far. However when i try to issue the UpdateTodoListCommand, i still get the 'Aggregate identifier must be non-null after applying an event. Make sure the aggregate identifier is initialized at the latest when handling the creation event.' error.It also doesn't break in the @EventSourcingHandler of the TodoListCreatedEvent, so that explains why the AggregateRoot doesn't have an AggregateIdentifier. Though I have no clue why that EventSourcingHandler isn't called?I understand you saying that it is important that the first event sets the identifier, but i would have expected that it would be the one in the aggregate root that i annotated with @EventSourcingHandler that listens to the creation event.Any more help would still be appreciated.
@Override
public boolean canHandle(Message<?> message) {
return typeMatches(message) && payloadType.isAssignableFrom(message.getPayloadType()) && parametersMatch(message);
}
from the AnnotatedMessageHandlingMember class that the payload is not assignable. The events are implemented using kotlin data classes (stole that idea from your youtube intro to axon), so something might be wrong there?