Axon错误:java.lang.IllegalArgumentException:工作单元已经有一个具有相同标识符的聚合

时间:2017-10-18 15:04:21

标签: java cqrs axon

我有一个处理Report Run Command的报表运行器聚合。聚合具有目标标识符,并且两个命令具有相同的目标标识符。

获得以下错误

  

java.lang.IllegalArgumentException:工作单元已经有一个具有相同标识符的聚合       在org.axonframework.common.Assert.isTrue(Assert.java:54)〜[axon-core-3.0.6.jar:3.0.6]       在org.axonframework.commandhandling.model.AbstractRepository.newInstance(AbstractRepository.java:84)〜[axon-core-3.0.6.jar:3.0.6]       at org.axonframework.commandhandling.AggregateAnnotationCommandHandler $ AggregateConstructorCommandHandler.handle(AggregateAnnotationCommandHandler.java:181)~ [axon-core-3.0.6.jar:3.0.6]       at org.axonframework.commandhandling.AggregateAnnotationCommandHandler $ AggregateConstructorCommandHandler.handle(AggregateAnnotationCommandHandler.java:170)~ [axon-core-3.0.6.jar:3.0.6]       at org.axonframework.commandhandling.AggregateAnnotationCommandHandler.handle(AggregateAnnotationCommandHandler.java:148)~ [axon-core-3.0.6.jar:3.0.6]       at org.axonframework.commandhandling.AggregateAnnotationCommandHandler.handle(AggregateAnnotationCommandHandler.java:40)〜[axon-core-3.0.6.jar:3.0.6]

这样的东西
public class ExecuteReportsAggregate
{
    @AggregateIdentifier
    private String reportId; 

    // Command Handler and Even Source Handlers
}

执行报告命令

@Value
public class ExecuteReportCommand
{
    @TargetAggregateIdentifier
    String reportId;
}

报告已执行的命令

@Value
public class ReportExecutedCommand
{
    // @TargetAggregateIdentifier
    private String reportId;
}

Spring boot看起来像这样

public static void main(String[] args)
{
    ConfigurableApplicationContext config = SpringApplication.run(SsmpPreopenCommand.class, args);
    CommandBus commandBus = config.getBean(CommandBus.class);

    commandBus.dispatch(GenericCommandMessage.asCommandMessage(new ExecuteReportCommand("12345",
        "asdfasdf Errors", "/home/teo", new ServiceCredentials())));

    // commandBus.dispatch(GenericCommandMessage.asCommandMessage(new
    // ReportExecutedCommand("12345")));
}

1 个答案:

答案 0 :(得分:0)

Axon正在处理您实施的聚合实例。因此,您可以使用@CommandHandler注释标记聚合的相关方法。

(通常)聚合应该有:

  • no-args构造函数
  • 具有作为第一个参数的命令的构造函数,由@CommandHandler注释
  • 标记
  • 至少一个标有@EventSourcingHandler注释的方法,接受执行此构造函数触发的事件作为第一个参数,该事件由AggregateLifecycle#apply()方法执行并设置由{{1标记的字段}}。
  • 接受命令作为标有AggregateIdentifier注释
  • 的第一个参数的任意数量的其他方法
  • 接受事件作为标有@CommandHandler注释
  • 的第一个参数的任意数量的其他方法

如果你在@EventSourcingHandler上发送第一个命令,Axon将尝试找到具有匹配标识符的Aggegate,因为它不存在但是通过调用构造函数并将命令传递给它来创建它。构造函数将调用CommandBus方法并触发事件(由Axon存储),因此从这个时间点开始,Axon将尝试使用相同的{{1}发送所有命令这个聚合实例。

如果您尝试使用SAME聚合标识符创建(并存储)另一个SAME类型的Aggregate实例,您将失败并看到上面的例外。

要避免,您要使用' create-on-check-fail'图案。查看我的thoughts on it here...

亲切的问候,

西蒙