我有一个正在处理报告运行命令的报告运行程序聚合。聚合具有目标标识符,并且两个命令具有相同的目标标识符。
出现以下错误
java.lang.IllegalArgumentException: The Unit of Work already has an Aggregate with the same identifier at org.axonframework.common.Assert.isTrue(Assert.java:54) ~[axon-core-3.0.6.jar:3.0.6] at 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 启动看起来像这样
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")));
}
最佳答案
Axon 正在处理您实现的聚合实例。因此,您可以通过使用 @CommandHandler
来标记 Aggregate 的相关方法。注释。
(通常)聚合应该具有:
- 无参数构造函数
- 以命令作为第一个参数的构造函数,标记为
@CommandHandler
注释 - 至少一种标有
@EventSourcingHandler
的方法注释,接受由执行此构造函数引发的事件作为第一个参数,该构造函数由AggregateLifecycle#apply()
执行方法并设置AggregateIdentifier
标记的字段. - 任何数量的其他方法,接受命令作为第一个参数,标记为
@CommandHandler
注释 - 任何数量的其他方法,接受事件作为第一个参数,标记为
@EventSourcingHandler
注释
如果您在 CommandBus
上发送第一个命令,Axon 将尝试查找具有匹配标识符的聚合,并且由于它尚不存在,因此通过调用构造函数并将命令传递给它来创建它。构造函数将调用AggregateLifecycle#apply()
方法并触发事件(由 Axon 存储),因此从此时开始,Axon 将尝试发送具有相同 TargetAggregateIdentifier
的所有命令。到这个聚合实例。
如果您尝试创建(并存储)具有相同聚合标识符的相同类型的另一个聚合实例,您将失败并看到上面的异常。
为了避免这种情况,您需要使用“create-on-check-fail”模式。看我的thoughts on it here...
亲切的问候,
西蒙
关于java - Axon 错误 : java. lang.IllegalArgumentException:工作单元已具有具有相同标识符的聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46813394/