Starting with Axon

Hi,

I'm building a simple application just to learn about CQRS and Axon
framework.
I have a main class where I'm initializing command and event bus.
Command is executed successfully and event is persisted, but event
listener doesn't fire.

CommandBus bus = new SimpleCommandBus();
    SimpleEventBus eventBus = new SimpleEventBus();

      FileSystemEventStore eventStore = new FileSystemEventStore(new
XStreamEventSerializer());
      try {
      eventStore.setBaseDir(new UrlResource("file:/base_dir_path"));
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }

      bus.subscribe(CreateCustomerCommand.class, new
CreateCustomerCommandHandler(eventBus, eventStore));
    bus.dispatch(new CreateCustomerCommand());

    AnnotationEventListenerAdapter listener = new
AnnotationEventListenerAdapter(new CustomerCreatedEventHandler(),
eventBus);
    listener.subscribe();

My event listener is a simple POJO:

public class CustomerCreatedEventHandler {

   @EventHandler
   public void handleContactCreatedEvent(CustomerCreatedEvent event) {
     System.out.println("Customer created");
   }
}

Please , tell me what Im doing wrong.

Cheers,

Hi,

I think the problem is in the command handler. Your wiring looks allright.

Currently, there is a feature missing that will be included in the 0.7 version. The problem you probably now have (it’s a guess, since command handler code is not included), is that new events are registered with your “UnitOfWork” (a.k.a. transaction), but they aren’t committed. Do you do a repository.save(modifiedAggregate) in your command handler? Alternatively, you can also do “CurrentUnitOfWork.commit()”. In the 0.7 release, you won’t have to do this anymore (see issue #94).

Hope this helps,

Cheers,

Allard

Oh, you can also register a SimpleUnitOfWorkInterceptor on your CommandBus. That is effectively what will happen out-of-the-box in 0.7.

Cheers,

Allard

Here is the code corresponding to my command handler.

public class CreateCustomerCommandHandler implements
CommandHandler<CreateCustomerCommand> {

  private CustomerRepository repository;

  public CreateCustomerCommandHandler(EventBus eventBus, EventStore
eventStore) {
    this.repository = new CustomerRepository(Customer.class);
    this.repository.setEventBus(eventBus);
    this.repository.setEventStore(eventStore);

  }

  public Object handle(CreateCustomerCommand command,
      CommandContext<CreateCustomerCommand> cctx ) throws Throwable {

    repository.save(new Customer(UUID.randomUUID()));

    return null;
  }
}

Note i'm saving an aggregate.

Thanks for your response Allard.

Ok, that’s not the problem.

I see you do “save(new Customer(UUID.random…))”. Does this constructor do an “apply(someEvent)”?

What kind of repository is the CustomerRepository? If it is a GenericEventSourcingRepository, you could get in trouble, as it expects the constructor with UUID parameter to be one that doesn’t apply any events.

The wiring looks correct, in either case.

Cheers,

Allard

I added a new constructor which doesn't apply any events, as you
suggested.
My Customer aggregate looks like:

public class Customer extends AbstractAnnotatedAggregateRoot {

  public Customer(UUID id) {
    super(id);
  }

  public Customer(String name, UUID id) {
    super(id);
    apply(new CustomerCreatedEvent(name));
  }

  @EventHandler
  protected void handleContactCreatedEvent(CustomerCreatedEvent event)
{

  }

}

The repository implemetation is as follows:

public class CustomerRepository extends
GenericEventSourcingRepository<Customer> {

  public CustomerRepository(Class<Customer> aggregateType) {
    super(aggregateType);
  }
}

I still can't make an event listener to fire : (.

I’ve quickly created a setup using the code you submitted. Did you change the following line:

repository.save(new Customer(UUID.randomUUID()));

into, for example:

repository.save(new Customer(“John”, UUID.randomUUID()));

When you do, you should see the event being fired. The UUID-only constructor is used by the GenericEventSourcingRepository, and is used to create a non-initialized instance of an aggregate, in order to replay events on it.

Cheers,

Allard

I do changed that line, but can't see the event being fired.
Here is my sample project in Eclipse.

http://www.megaupload.com/?d=X9R3C18Z

Thanks for you answers, Allard.

Cheers

Well, this explains it:

bus.dispatch(new CreateCustomerCommand());

AnnotationEventListenerAdapter listener = new AnnotationEventListenerAdapter(new CustomerCreatedEventHandler(), eventBus);
listener.subscribe();

First, you dispatch the command, and only after that, you register the listener. Try switching those lines around:

AnnotationEventListenerAdapter listener = new AnnotationEventListenerAdapter(new CustomerCreatedEventHandler(), eventBus);
listener.subscribe();

bus.dispatch(new CreateCustomerCommand());

Cheers,

Allard

That worked !!!!!!

Thank you sir :smiley: