Spring 值对象为@AggregateIdentifier和@TargetAggregateIdentifier
首先,我为这篇很长的文章道歉。有相当多的代码要显示有一个问题的详细理解,因此失去了东西张贴。。。请您阅读全文:-) 我正在尝试使用Axon框架和Spring引导应用程序开发一个基于事件源的应用程序。我在下面提供了许多类定义,它们构成了聚合、命令和事件实现 我编写了一个非常简单的测试应用程序(Spring),它只向Axon发送一个CreateAppointmentCommand。此create命令使用手动分配的AppointmentId(它是AbstractId的子类)并返回此ID供以后使用。这没什么错,Appointment中的构造函数命令处理程序按预期调用,相应的ApppointmentCreatedEvent被激发,Appointment类也按预期处理。到目前为止,一切顺利。 当我使用create命令返回的ID发送ConfirmAppointmentCommand时,问题就出现了。在这些情况下,我会收到一条错误消息: 命令“confirMapPointCommand”导致org.axonframework.commandhandling.CommandExecutionException(为类约会提供的id类型错误。应为:类约会id,获取类java.lang.String) 我不了解此设置中与此错误消息相关的一些内容:Spring 值对象为@AggregateIdentifier和@TargetAggregateIdentifier,spring,domain-driven-design,cqrs,event-sourcing,axon,Spring,Domain Driven Design,Cqrs,Event Sourcing,Axon,首先,我为这篇很长的文章道歉。有相当多的代码要显示有一个问题的详细理解,因此失去了东西张贴。。。请您阅读全文:-) 我正在尝试使用Axon框架和Spring引导应用程序开发一个基于事件源的应用程序。我在下面提供了许多类定义,它们构成了聚合、命令和事件实现 我编写了一个非常简单的测试应用程序(Spring),它只向Axon发送一个CreateAppointmentCommand。此create命令使用手动分配的AppointmentId(它是AbstractId的子类)并返回此ID供以后使用。这没
@Aggregate
@Entity
@Table(name = "t_appointment")
public final class Appointment extends AbstractEntity<AppointmentId> {
//JPA annotated class members left out for brevity
@PersistenceConstructor
private Appointment() {
super(null);
//Sets all remaining class members to null.
}
@CommandHandler
private Appointment(CreateAppointmentCommand command) {
super(command.getAggregateId());
validateFields(getEntityId(), ...);
AggregateLifecycle.apply(new AppointmentCreatedEvent(getEntityId(), ...);
}
@EventSourcingHandler
private void on(AppointmentCreatedEvent event) {
validateFields(event.getAggregateId(), ...);
initFields(event.getAggregateId(), ...);
}
private void validateFields(AppointmentId appointmentId, ...) {
//Check if all arguments are within the required boundaries.
}
private void initFields(AppointmentId appointmentId, ...) {
//Set all class level variables to passed in value.
}
@CommandHandler
private void handle(ConfirmAppointmentCommand command) {
AggregateLifecycle.apply(new AppointmentConfirmedEvent(command.getAggregateId()));
}
@EventSourcingHandler
private void on(AppointmentConfirmedEvent event) {
confirm();
}
public void confirm() {
changeState(State.CONFIRMED);
}
//Similar state changing command/event handlers left out for brevity.
private void changeState(State newState) {
switch (state) {
...
}
}
//All getter methods left out for brevity. The aggregate does NOT provide any setters.
@Override
public String toString() {
return "Appointment [...]";
}
}
在聚合中,使用了许多命令和事件。每个命令都是command的子类
@SuppressWarnings("serial")
public abstract class Command<AGGREGATE_ID extends AbstractId> implements Serializable{
private AGGREGATE_ID aggregateId;
@TargetAggregateIdentifier
private String targetId;
protected Command(AGGREGATE_ID aggregateId) {
if(aggregateId == null) {
throw new InvalidArgumentException(...);
}
this.aggregateId = aggregateId;
this.targetId = aggregateId != null ? aggregateId.getId() : null;
}
public final AGGREGATE_ID getAggregateId() {
return aggregateId;
}
}
@SuppressWarnings(“串行”)
公共抽象类命令实现可序列化{
私有聚合_idaggregateId;
@目标聚集标识符
私有字符串targetId;
受保护命令(聚合ID聚合ID){
if(aggregateId==null){
抛出新的InvalidArgumentException(…);
}
this.aggregateId=aggregateId;
this.targetId=aggregateId!=null?aggregateId.getId():null;
}
公共最终聚合\u ID getAggregateId(){
返回集合ID;
}
}
一个指定的命令类(这在我的方法中造成了困难)是confirmappointCommand,它实际上只是基本命令类的一个具体实现,因此实现非常简单
public final class ConfirmAppointmentCommand extends Command<AppointmentId> {
private static final long serialVersionUID = 6618106729289153342L;
public ConfirmAppointmentCommand(AppointmentId appointmentId) {
super(appointmentId);
}
}
public final class AppointmentCreatedEvent extends DomainEvent<AppointmentId> {
private static final long serialVersionUID = -5265970306200850734L;
//Class members left out for brevity
public AppointmentCreatedEvent(AppointmentId appointmentId, ...) {
super(appointmentId);
//Check to verify the provided method arguments are left out.
//Set all verified class members to the corresponding values.
}
//Getters for all class members, no setters are being implemented.
}
public final类confirmappointCommand扩展命令{
私有静态最终长serialVersionUID=6618106729289153342L;
公共确认点命令(任命ID任命ID){
超级(任命ID);
}
}
CreateAppointmentCommand与ConfirmAppointCommand非常相似,定义如下
public final class CreateAppointmentCommand extends Command<AppointmentId> {
private static final long serialVersionUID = -5445719522854349344L;
//Some additional class members left out for brevity.
public CreateAppointmentCommand(AppointmentId appointmentId, ...) {
super(appointmentId);
//Check to verify the provided method arguments are left out.
//Set all verified class members to the corresponding values.
}
//Getters for all class members, no setters are being implemented.
}
public final类createAppointCommand扩展命令{
私有静态最终长serialVersionUID=-5445719522854349344L;
//为了简洁起见,遗漏了一些额外的类成员。
公共CreateAppointmentCommand(AppointmentId AppointmentId,…){
超级(任命ID);
//检查以验证是否遗漏了提供的方法参数。
//将所有已验证的类成员设置为相应的值。
}
//对于所有类成员,没有实现任何setter。
}
对于项目中使用的不同事件,使用了类似的方法。所有事件都是下面定义的基本DomainEvent类的子类
@SuppressWarnings("serial")
public abstract class DomainEvent<T extends AbstractId> implements Serializable{
private T aggregateId;
protected DomainEvent(T aggregateId) {
if(aggregateId == null) {
throw new InvalidArgumentException(ErrorCodes.AGGREGATE_ID_MISSING);
}
this.aggregateId = aggregateId;
}
public final T getAggregateId() {
return aggregateId;
}
}
@SuppressWarnings(“串行”)
公共抽象类DomainEvent实现可序列化{
私人T-aggregateId;
受保护域事件(T aggregateId){
if(aggregateId==null){
抛出新的InvalidArgumentException(ErrorCodes.AGGREGATE\u ID\u MISSING);
}
this.aggregateId=aggregateId;
}
公共最终T getAggregateId(){
返回集合ID;
}
}
任命CreateDevent相当直截了当
public final class ConfirmAppointmentCommand extends Command<AppointmentId> {
private static final long serialVersionUID = 6618106729289153342L;
public ConfirmAppointmentCommand(AppointmentId appointmentId) {
super(appointmentId);
}
}
public final class AppointmentCreatedEvent extends DomainEvent<AppointmentId> {
private static final long serialVersionUID = -5265970306200850734L;
//Class members left out for brevity
public AppointmentCreatedEvent(AppointmentId appointmentId, ...) {
super(appointmentId);
//Check to verify the provided method arguments are left out.
//Set all verified class members to the corresponding values.
}
//Getters for all class members, no setters are being implemented.
}
public final class AppointmentCreatedEvent
public final class AppointmentConfirmedEvent extends DomainEvent<AppointmentId> {
private static final long serialVersionUID = 5415394808454635999L;
public AppointmentConfirmedEvent(AppointmentId appointmentId) {
super(appointmentId);
}
}