import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.modelling.command.AggregateMember;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "giftCardId")
private List<GiftCardTransaction> transactions = new ArrayList<>();
private int remainingValue;
public GiftCard(IssueCardCommand cmd) {
if (cmd.getAmount() <= 0) {
throw new IllegalArgumentException("amount <= 0");
remainingValue = cmd.getAmount();
apply(new CardIssuedEvent(cmd.getCardId(), cmd.getAmount()));
public void handle(RedeemCardCommand cmd) {
if (cmd.getAmount() <= 0) {
throw new IllegalArgumentException("amount <= 0");
if (cmd.getAmount() > remainingValue) {
throw new IllegalStateException("amount > remaining value");
if (transactions.stream().map(GiftCardTransaction::getTransactionId).anyMatch(cmd.getTransactionId()::equals)) {
throw new IllegalStateException("TransactionId must be unique");
remainingValue -= cmd.getAmount();
transactions.add(new GiftCardTransaction(id, cmd.getTransactionId(), cmd.getAmount()));
apply(new CardRedeemedEvent(id, cmd.getTransactionId(), cmd.getAmount()));
protected void on(CardReimbursedEvent event) {
this.remainingValue += event.getAmount();
protected GiftCard() { } // 9.