问题描述
我有一个聚合Organization
,可以有多个地址。因此,我们已将此OrganizationDeliveryAddress
建模为聚合成员。在OrganizationDeliveryAddress
上,我们为实体本身命令和事件源处理程序。
这是我当前的实现方式:
@Aggregate
public class Organization {
private @AggregateIdentifier
@NonNull UUID organizationId;
@AggregateMember
private final List<OrganizationDeliveryAddress> deliveryAddresses = new ArrayList<>();
@CommandHandler
public UUID on(AddOrganizationDeliveryAddressCommand command) {
val addressId = UUID.randomUUID();
val event = new OrganizationDeliveryAddressAddedEvent(command.getorganizationId(),addressId,command.getAddress());
AggregateLifecycle.apply(event);
return addressId;
}
@EventSourcingHandler
public void on(OrganizationDeliveryAddressAddedEvent event) {
val address = new OrganizationDeliveryAddress(event.getorganizationDeliveryAddressId(),false);
deliveryAddresses.add(address);
}
}
public class OrganizationDeliveryAddress {
private @EntityId
@NonNull UUID organizationDeliveryAddressId;
@CommandHandler
public void on(RemoveOrganizationDeliveryAddressCommand command) {
AggregateLifecycle.apply(new OrganizationDeliveryAddressRemovedEvent(command.getorganizationId(),command.getorganizationDeliveryAddressId()));
}
@EventSourcingHandler
public void on(@SuppressWarnings("unused") OrganizationDeliveryAddressRemovedEvent event) {
if (organizationDeliveryAddressId.equals(event.getorganizationDeliveryAddressId())) {
AggregateLifecycle.markDeleted();
}
}
}
我们要删除其中一个地址,但看起来不仅是地址,而是整个聚合都已删除。
所以这是我的问题:如何指示Axon Framework删除OrganizationDeliveryAddress
聚合成员?
解决方法
AggregateMember
本身不是聚合服务器,而只是另一个聚合服务器的成员。这就是为什么如果调用AggregateLifecycle.markDeleted();
会将聚合本身标记为已删除的原因。
要“删除” AggregateMember
,您应该做与添加相反的操作,这意味着您可以在聚合上使用@EventSourcingHandler
方法来监听OrganizationDeliveryAddressRemovedEvent
。这种方法将负责在您的AggregateMember(deliveryAddresses
)上找到正确的DeliveryAddress,甚至更好的是Map
,如下所示,并将其从中删除。伪代码可能是这样的:
// Organization.java
...
@AggregateMember
private final Map<UUID,OrganizationDeliveryAddress> deliveryAddressItToDeliveryAddress = new HashMap<>();
...
@EventSourcingHandler
public void on(@SuppressWarnings("unused") OrganizationDeliveryAddressRemovedEvent event) {
Assert.isTrue(deliveryAddressItToDeliveryAddress.containsKey(event.getOrganizationDeliveryAddressId()),"We do not know about this address");
deliveryAddressItToDeliveryAddress.remove(event.getOrganizationDeliveryAddressId());
}