如何在Axon上删除AggregateMember?

问题描述

我有一个聚合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());
}