Hello everyone.
My team has been successfully developed the first microservice in a soon-to-be larger micro-service ecosystem using the Axon Framework. Thus, the time has come for us to start developing the other services, that will communicate with this one.
The root of the problem arises from the fact that we make use of the same Entity( in a Bounded Context way of speaking) in both the applications. Apart from some common fields and the ability to handle 2 types of events, these two subtypes differ largely when it comes to command-handling and event-sourcing. So we thought that having a base AbstractAggreate
with the common fields and and the 2 abstract EventSourcingHandler
methods inside a common module will be the right choice for developing further.
However, I cannot put my finger on how exactly can we benefit from Aggregate Polymorphism and instantiation if the base AbstractAggregate
, ATypeAggregate
and BTypeAggregate
all reside in 3 different Maven modules. How can we make sure that, inside module A we will instantiate ATypeAggregate
and inside module B we will instantiate BTypeAggregate
?
Here is a snippet on the base aggregate:
public abstract class BaseAggregate implements Serializable {
@AggregateIdentifier
protected AggId partnerId;
protected AggType discriminator;
private String code;
protected LegalForm legalForm;
protected BusinessDetails businessDetails;
private PersonalContact personalContact;
private LanguageCode language = LanguageCode.getDefault();
@EventSourcingHandler
public abstract void on(RemoteSourceDataSyncedEvent event , @Autowired ModelMapper modelMapper);
}
And here is how the BType
aggregate should look like:
@Aggregate
@Getter
@Setter
public class BType extends BaseAggregate {
// private fields emitted for brevity
@AggregateMember(type = Member1.class,
eventForwardingMode = ForwardMatchingInstances.class)
private Map<Long,Member1> addresses = new HashMap<>();
@AggregateMember(type = Member2.class,
eventForwardingMode = ForwardMatchingInstances.class)
private Map<String, Member2> roles = new HashMap<>();
@CommandHandler
@CreationPolicy(AggregateCreationPolicy.CREATE_IF_MISSING)
public void on(CreateBTypeCommand, @Autowired ModelMapper modelMapper) {
//here we should handle creation of this subtype
}
@EventSourcingHandler
@Override
public void on(ERPPartnerDataSyncedEvent syncedEvent, @Autowired ModelMapper modelMapper) {
//overridden way of handling the event applied from the base class
}
AType
and BType
will have @CommandHandlers
that will instatiate them differently, but each should be able to record that kind of SyncingEvent.
After a first attempt to implement such a behaviour, when dispatching a CreateBTypeCommand
the command returns with error:
Failed to acquire lock for identifier(17006133), maximum attempts exceeded (6000)
After some debugging I found that it all goes well until this stage:
protected LockAwareAggregate<T, A> doLoadOrCreate(String aggregateIdentifier,
Callable<T> factoryMethod) throws Exception {
Lock lock = lockFactory.obtainLock(aggregateIdentifier);
Thank you in advance for taking the time to read my question and I am looking forward for any kind of help!