我收到以下错误。 Axon版本3.3.3
org.axonframework.eventsourcing.IncompatibleAggregateException: 应用事件后,聚合标识符必须为非null。使 确保聚合标识符最迟在何时初始化 处理创建事件。
我已经创建了一个UserAggregate。它包含2个事件:
我能够生成第一个(UserCreated)事件,它以序列0保存在事件存储中,但是在生成第二个事件时,出现了上述错误。
对此有何建议?
@Aggregate
public class UserAggregate {
@AggregateIdentifier
private String id;
private String email;
private String password;
public UserAggregate(String id, String email, String password) {
super();
this.id = id;
this.email = email;
this.password = password;
}
@CommandHandler
public UserAggregate(CreateUser cmd) {
AggregateLifecycle.apply(new UserCreated(cmd.getId(), cmd.getEmail(), cmd.getPassword()));
}
@CommandHandler
public void handle(UpdateUserCmd cmd) {
AggregateLifecycle.apply(new UpdateUserEvent(cmd.getId(), cmd.getEmail(),""));
}
@EventSourcingHandler
public void userCreated(UserCreated event) {
System.out.println("new User: email " + event.getEmail() +" Password: "+ event.getPassword());
setId(event.getId());
}
@EventSourcingHandler
public void updateUserEvent(UpdateUserEvent event) {
System.out.println("new User: email " + event.getEmail());
setId(event.getId());
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public UserAggregate() {
}
}
答案 0 :(得分:0)
当遵循聚合的事件源范例时,我通常建议在代码中出现两种类型的构造函数:
在您的示例中,我看到了第三个构造函数,用于设置chmod
,id
和email
。
我的猜测是,此构造函数当前可能会妨碍password
实现以进行正确的验证。
如果未在构造函数命令处理程序之后设置EventSourcedAggregate
带注释的字段 ,则您收到的异常将仅发生(在您的情况下为{{1} }结束了它的工作单元。
因此,看到您的代码,我唯一的直觉是这个“野生的,未使用的”构造函数,它可能会阻塞事物。
最后,我需要推荐您使用更新版本的Axon。 3.3.3与当前版本4.2相距甚远。 此外,Axon 3.x版本未进行任何积极的开发。 因此,明智的做法是升级版本,因为您仍在定义命令模型,所以我认为这没什么大不了的。
更新
我刚刚关闭了您打开的Framework问题。 Axon提供了完全不同的方式来绑定Message的调度和处理,为您提供比(Spring)AOP更清晰的拦截点。
如果您遵循建议的准则,在@AggregateIdentifier
中使用UserAggregate(CreateUser)
/ MessageDispatchInterceptor
或更细粒度的选项,则可以解决您正在寻找的跨领域问题。 / p>
就日志记录而言,该框架甚至提供了MessageHandlerInterceptor
来执行您需要的操作。不需要AOP。
希望这可以帮助您解决Narasimha。
答案 1 :(得分:0)
我仍然逐渐了解Axon,但这是我设法解决此问题的方法。基本上,错误是指在实例化UserAggregate
时,聚合标识符(即主键)不能为null,并且必须具有值。
生命周期的顺序是
EventSourcingHandler
来处理上一步中应用的事件根据上述步骤,您需要执行以下操作:
protected UserAggregate() {
}
@CommandHandler
public UserAggregate(CreateUser cmd) {
AggregateLifecycle.apply(
new UserCreated(cmd.getId(),cmd.getEmail(),cmd.getPassword()));
}
UserCreated
事件
@EventSourcingHandler
public void on(UserCreated userCreated) {
// this is where we instantiate the aggregate identifier
this.id = userCreated.getId();
//assign values to other fields
this.email = userCreated.getEmail();
this.password = userCreated.getPassword();
}
这是完整的示例:
@Aggregate
public class UserAggregate {
@AggregateIdentifier
private String id;
private String password;
private String email;
protected UserAggregate() {
}
@CommandHandler
public UserAggregate(CreateUser cmd) {
AggregateLifecycle.apply(
new UserCreated(cmd.getId(),cmd.getEmail(),cmd.getPassword()));
}
@EventSourcingHandler
public void on(UserCreated userCreated) {
// this is where we instantiate the aggregate identifier
this.id = userCreated.getId();
//assign values to other fields
this.email = userCreated.getEmail();
this.password = userCreated.getPassword();
}
}
答案 2 :(得分:-1)
谢谢@Steven的回复。
我也可以使用Axon 4.2(最新)版本重现此问题。 在我的项目中删除以下AOP代码后,该问题会自动解决。 看起来Axon缺少与AOP功能的兼容性。
AOP代码:
2019-10-07 12:52:41.689 WARN 31736 --- [ault-executor-0] o.a.c.gateway.DefaultCommandGateway : Command 'com.ms.axonspringboot.commands.UpdateUserCmd' resulted in org.axonframework.commandhandling.CommandExecutionException(Aggregate identifier must be non-null after applying an event. Make sure the aggregate identifier is initialized at the latest when handling the creation event.)
2019-10-07 12:52:41.710 ERROR 31736 --- [nio-7070-exec-3] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] threw exception
org.axonframework.axonserver.connector.command.AxonServerRemoteCommandHandlingException: An exception was thrown by the remote message handling component: Aggregate identifier must be non-null after applying an event. Make sure the aggregate identifier is initialized at the latest when handling the creation event.
at org.axonframework.axonserver.connector.ErrorCode.lambda$static$8(ErrorCode.java:84) ~[axon-server-connector-4.2.jar:4.2]
at org.axonframework.axonserver.connector.ErrorCode.convert(ErrorCode.java:180) ~[axon-server-connector-4.2.jar:4.2]
Axon 4.2版本错误日志
posts.forEach