registering standalone command hanlders (not in aggregate) with spring boot

938 views
Skip to first unread message

Lukáš Vasek

unread,
Dec 15, 2016, 3:13:20 AM12/15/16
to Axon Framework Users
Hi,
within axon 2.x I was creating command handlers as spring's @Component. Now in axon 3.x this doesn't work anymore.
What is the minimal configuration needed to register command handler with it's repository?

I was trying this:

@Aggregate
public class AccessorAggregateRoot implements Serializable {

private static final long serialVersionUID = -6507215786865192829L;

@AggregateIdentifier
private AccessorId accessorId;
...
}

@Configuration
public class AccessorCommandConfiguration {

@Bean
Repository<AccessorAggregateRoot> accessorAggregateRootRepository(AxonConfiguration axonConfiguration) {
return axonConfiguration.repository(AccessorAggregateRoot.class);
}
}


@Component
public class AccessorCommandHandler implements IAggregateLoader<AccessorAggregateRoot, AccessorId> {

private Repository<AccessorAggregateRoot> accessorRepository;
private PasswordEncoder passwordEncoder;

@Autowired
public AccessorCommandHandler(
Repository<AccessorAggregateRoot> accessorAggregateRootRepository, PasswordEncoder passwordEncoder) {
this.accessorRepository = accessorAggregateRootRepository;
this.passwordEncoder = passwordEncoder;
}

}

but I'm getting the exception:

BeanCurrentlyInCreationException: Error creating bean with name 'accessorAggregateRootRepository': Requested bean is currently in creation: Is there an unresolvable circular reference?



If I remove the repository config from AccessorCommandConfiguration then it seems that repository is not configured, or maybe it's configured after commandhandler

***************************

APPLICATION FAILED TO START

***************************


Description:


Parameter 0 of constructor in net.docucom.cloud.accessor.command.AccessorCommandHandler required a bean of type 'org.axonframework.commandhandling.model.Repository' that could not be found.



Action:


Consider defining a bean of type 'org.axonframework.commandhandling.model.Repository' in your configuration.



The last thing which worked for me is to remove @Component from commandhandler and register it within @Configuration like this
@Configuration
public class AccessorCommandConfiguration {

@Bean
AccessorCommandHandler accessorCommandHandler(AxonConfiguration axonConfiguration, PasswordEncoder passwordEncoder) {
return new AccessorCommandHandler(axonConfiguration.repository(AccessorAggregateRoot.class), passwordEncoder);
}
}

is this the correct and simplest way?

how can we customize the repository?

Thanks

Allard Buijze

unread,
Dec 16, 2016, 3:54:00 PM12/16/16
to Axon Framework Users
Hi,

using Spring, if you want to customize the repository, simply define a repository bean, but don't use the AxonConfiguration to get one. The issue here is that you're asking the AxonConfiguration to provide a repository instance, but the configuration isn't ready to provide one yet. Using Spring, it works the other way round (defining a repository will configure it with the configuration).

Anyway, the @Aggregate annotation allows you to configure the name of the repository bean to use to load that aggregate. If you don't define one, then Axon will automatically create one (provided you use spring-boot-auto-configuration and have the axon-spring-boot-autoconfigure module included).

Hope this helps.

Cheers,

Allard

--
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.

Mavlarn Tuohuti

unread,
May 30, 2018, 3:35:39 AM5/30/18
to Axon Framework Users
I also got this problem in axon 3.2.
I use axon-spring-boot-starter , and in my simple example, I try to autowire repository like this:

@Autowired
private Repository<Account> accountRepository;

But there is an error as above, that could not be found.

Steven van Beelen

unread,
May 30, 2018, 7:27:28 AM5/30/18
to axonfr...@googlegroups.com
Hi Mavlarn,

For what purpose are you trying to wire the Aggregate `Repository`?
Typical use case to wire an Aggregate Repository would be to be able to load or create Aggregate instances directly on it because you've got `@CommandHandler` annotated functions on a service.
If that's the case however, I'd suggest setting the `@CommandHandler` annotations in your Aggregate class directly, is that introduce a simpler solution for you.

If you're wiring the Repository to query the Aggregate it's state and you're doing Event Sourcing, then I'd also suggest against wiring it yourself.
In this case you're mixing up the command and query side of your application, and as such I'd suggest introducing a dedicated query model which is based off of the events published from your Aggregates.

The above are mainly suggestions though, maybe you've got another entirely valid reason to wire the Repository somewhere.
So to ask a simpler question, from which part in your application does the `@Autowired priver Repository<Account> accountRepository;` line stem?

Cheers,
Steven

--

Mavlarn Tuohuti

unread,
May 31, 2018, 5:12:50 AM5/31/18
to Axon Framework Users
I have a class like OrderCommandHandler, annotated as a Component.
@Component
public clsss OrderCommandHandler {
 
@Autowired
 
private Repository<Order> orderRepository;
  @Autowired
 
private Repository<OrderProduct> orderProductRepository;

 
@CommandHandler
 
public void handle(SomeCommand cmd) {
   
...
 
}
}

I

Sometime I want to handle one command based on 2 aggregates,these 2 aggregate maybe aggregate and its member. And sometime,when I handle order command,I need to get some value of related product.

I know I can spit some command into 2, to avoid access 2 aggregates in one function. But if it is  available, I think it will be convenient to do as above.

在 2018年5月30日星期三 UTC+8下午7:27:28,Steven van Beelen写道:

Steven van Beelen

unread,
Jun 13, 2018, 11:07:16 AM6/13/18
to axonfr...@googlegroups.com
Hi Mavlarn,

First off, my apologies for the late reply.
You're response somehow slipped between the gaps of other work..

Any how, back to your issue.
I've been able to reproduce your scenario; thus, not being able to wire an aggregate Repository as a bean in my own Components/Services.
The Spring (Boot) configuration code in Axon showed me that we're currently not exposing the Repository as a bean in the ApplicationContext.

To resolve this, I've created the following issue.
That issue describes the idea we have to resolve this, so that framework-users like yourself can wire the automatically created aggregate Repository.

For now however, you'll need a work around of course.
I suggest to instantiate the aggregate Repository yourself in your application and annotating it with `@Bean`.
Doing so will surely allow you to wire the Repositories you need in your other components.

If you've got time to wait though, you could track issue #620 for the progress.
I assume we'll introduce it in release 3.3, which we're planning to release this week.

Hope this helps you out Mavlarn!

Cheers,
Steven

Mavlarn Tuohuti

unread,
Jun 14, 2018, 5:01:54 AM6/14/18
to axonfr...@googlegroups.com
Thanks for your reply. I am from China, so we have different working time.
Now I created the bean as you suggest. 

And thanks again. Axon is really great framework.

Steven van Beelen

unread,
Jun 14, 2018, 5:20:20 AM6/14/18
to axonfr...@googlegroups.com
Hi Mavlarn,

I hope my suggestion resolved your issue?
If not, the fix should be in soon :-)

Great to hear you like the framework!
I hope we can keep it a pleasant experience for time to come.

Cheers,
Steven
Reply all
Reply to author
Forward
0 new messages