【问题标题】:multi-entity aggregates event handling is not working多实体聚合事件处理不起作用
【发布时间】:2021-08-09 05:43:11
【问题描述】:

我有一个这样的聚合根 它的信用卡聚合,其中包含有关付款、ID、汇款的记录

@NoArgsConstructor
@EqualsAndHashCode
@Log4j2
@Aggregate
public class CreditCard {

@AggregateIdentifier
private String id;

@AggregateMember
private List<CreditCardTransaction> transactions= new ArrayList<>();
private int limit; 
@CommandHandler
public CreditCard(CreditCardCreatedCmd cmd) {
    log.info(cmd.getId()+","+cmd.getLimit());
    AggregateLifecycle.apply(new CreditCardCreatedEvt(cmd.getId(), cmd.getLimit())); 
}

@EventSourcingHandler
public void on(CreditCardCreatedEvt evt) {
    id = evt.getId();
    limit = evt.getLimit();
    log.info("[CreditCardCreatedEvt] id : "+id);

}

@CommandHandler
public void on(PaymentCmd cmd) throws LimitExceededException {

    if (limit < cmd.getValue())
        throw new LimitExceededException();
 
    AggregateLifecycle.apply(new PaymentSuccessEvt(UUID.randomUUID().toString(), cmd.getValue())); 

}

@EventSourcingHandler
public void handle(PaymentSuccessEvt evt) {
    log.info("[PaymentSuccessEvt] transactionId : "+evt.getTransactionId());
    transactions.add(new CreditCardTransaction(evt.getTransactionId(), evt.getValue()));
}

}

和有支付记录的子实体

@Log4j2
@NoArgsConstructor
public class CreditCardTransaction {

    @EntityId
    private String transactionId;

    private int transactionValue;
    private boolean refund = false;

    private LocalDateTime paymentDate;

    public CreditCardTransaction(String transactionId, int transactionValue) {
        this.transactionId = transactionId;
        this.transactionValue = transactionValue;
        this.paymentDate = LocalDateTime.now();
    }

    public String getTransactionId() {
        return transactionId;
    }

    @CommandHandler
    public void on(RefundCmd cmd) {

        if (ChronoUnit.DAYS.between(paymentDate, cmd.getToday()) >= 30)
            throw new DueTimeOverException();
       
        log.info("[RefundCmd] "+cmd.getTransactionId());
        AggregateLifecycle.apply(new RefundEvt(cmd.getCardId(), cmd.getTransactionId()));
    }

    @EventSourcingHandler
    public void hanlde(RefundEvt evt) {
        if (transactionId.equals(evt.getTransactionId())) {
            transactionValue*=-1;
            paymentDate=LocalDateTime.now(); 
            refund = true;
            log.info("[RefundEvt accepted] transactionId : "+transactionId);
        }
        log.info("[RefundEvt rejected] transactionId : "+transactionId);
    }

}

@Data@NoArgsConstructor@AllArgsConstructor
public class RefundCmd {
    @TargetAggregateIdentifier
    String cardId;
    String transactionId;
    LocalDateTime today;
}

@Data@NoArgsConstructor
public class RefundEvt {
    String cardId; 
    String transactionId; 
    LocalDateTime today;

    public RefundEvt(String cardId, String transactionId) {
        this.cardId = cardId;
        this.transactionId = transactionId;
        today=LocalDateTime.now();
    }
}

当我像这样向我的子实体发送命令时

commandGateway.send(new RefundCmd(cardId, transactionId,LocalDateTime.now()));

该子实体的 CommandHandler 工作,但 eventsourcinghandler 无法获取事件

我得到了如下异常

Command 'com.cqrs.order.demo.command.RefundCmd' resulted in org.axonframework.commandhandling.CommandExecutionException(Cannot request current Scope if none is 
active)

我这样做是参考this

【问题讨论】:

  • 可能您需要更改聚合标识符名称以匹配聚合和命令中的名称。在聚合上将其命名为 cardId 或在 RefundCmd 上将其命名为 id。
  • 感谢您的回复,但它不起作用

标签: spring-boot cqrs axon


【解决方案1】:

发布事件时 使用org.axonframework.modelling.command.AggregateLifecycle.apply 不是org.axonframework.commandhandling.model.AggregateLifecycle.apply

【讨论】:

  • 您是否依赖于旧的 AxonFramework 版本?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 2021-07-22
  • 2015-03-31
  • 1970-01-01
相关资源
最近更新 更多