I have three catalogs, A, B and C, i want to add a new product to the catalog B.
I have an aggregate for product, so i create a command CreateProductCommand which is responsible for creating the product.
In the same time i want to update the products list in the CatalogAggregate for a specific catalog (for my example the catalog B). What’s the best approach to do that ?
@Aggregate
public class CatalogAggregate {
@AggregateIdentifier
private String catalogtId;
private List<Product> products;
}
@Aggregate
public class ProductAggregate {
@AggregateIdentifier
private String productId;
private String name;
private short price;
}
public String createProduct(Product product) {
return (String) commandGateway.sendAndWait(new CreateProductCommand(UUID.randomUUID().toString(), product.getName(), product.getPrice()));
}
Hi Aymen,
Thanks for using our forum. This is a suggestion how you can do it using Axon:
The Product aggregate:
import java.util.UUID;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.eventsourcing.EventSourcingHandler;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.modelling.command.AggregateLifecycle;
import org.axonframework.spring.stereotype.Aggregate;
import io.axoniq.dev.samples.api.CreateProductCommand;
import io.axoniq.dev.samples.api.ProductCreatedEvent;
@Aggregate
public class ProductAggregate {
@AggregateIdentifier
private UUID productId;
@CommandHandler
ProductAggregate(CreateProductCommand command){
AggregateLifecycle.apply(new ProductCreatedEvent(command.getProductId()));
}
@EventSourcingHandler
public void on(ProductCreatedEvent event){
this.productId = event.getProductId();
}
}
And the CatalogAggregate
import static org.axonframework.modelling.command.AggregateLifecycle.apply;
import java.util.List;
import java.util.UUID;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.eventsourcing.EventSourcingHandler;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.modelling.command.AggregateMember;
import org.axonframework.spring.stereotype.Aggregate;
import io.axoniq.dev.samples.api.AddProductToCatalogCommand;
import io.axoniq.dev.samples.api.CatalogCreatedEvent;
import io.axoniq.dev.samples.api.CreateCatalogCommand;
import io.axoniq.dev.samples.api.ProductAddedToCatalogEvent;
@Aggregate
public class CatalogAggregate {
@AggregateIdentifier
private UUID catalogId;
@AggregateMember
private List<UUID> products;
@CommandHandler
public CatalogAggregate(CreateCatalogCommand command) {
apply(new CatalogCreatedEvent(command.getCatalogId()));
}
@CommandHandler
public void handle(AddProductToCatalogCommand command){
apply(new ProductAddedToCatalogEvent(command.getCatalogId(), command.getProductId()))
}
@EventSourcingHandler
public void on(CatalogCreatedEvent event){
this.catalogId = event.getCatalogId();
}
@EventSourcingHandler
public void on (ProductAddedToCatalogEvent event){
this.products.add(event.getProductId());
}
}
If you have your aggregates set up like this you can listen to the ProductCreatedEvent in an event handling component and send a command to the CatalogAggregate:
@Component
public class ProductEventHandler {
@EventHandler
public void on(ProductCreatedEvent event, CommandGateway commandGateway){
commandGateway.send(new AddProductToCatalogCommand(event.getProductId(), event.getProductId()));
}
}
I hope this makes sense.
I would like to mention that on Wednesday my colleague @Steven_van_Beelen will provide a free webinar explaining DDD,CQRS and ES and the basics of Axon Framework. https://axoniq.io/event-overview/fast-lane-axon-framework-online-training-nr-10
Kind regards,
Yvonne
1 Like