Easy beginning: AbstractJpaAggregateRoot and GenericJpaRepository sample

Hi to all,

I'm newbie on Axon and CQRS, but I have done quite a hard job this
week searching and reading all I found :slight_smile:

We have a classic JPA based application, currently working under the
CRUD model.

All examples I have found are made with Event-Sourced Aggregates.

But our bussiness case is not as related to Event-Sourcing, but to be
able to design a good API based on Commands and Events to our JPA-
based application that can scale well on the future (perhaps to the
CQRS paradigm).

Our JPA-based Entities can have easily 10 - 20 fields that can be
updated, changing their state (that's really common on most CRUD
applications). Imagine a screen where all 20 fields are changed.
- Should we passed all 20 fields as parameters to the command?

As written on 1.3.3 reference guide, it should be possible to
implement our Aggregate Root inheriting/extending from
AbstractJpaAggregateRoot and adding all JPA-based .

But seems that AbstractJpaAggregateRoot has not been included on the
axon-core-1.3.3.jar.
It should be on the org.axonframework.domain package, but nothing
found there. See it as on version 0.7.x:
http://www.axonframework.org/apidocs/0.7.x/org/axonframework/domain/AbstractJpaAggregateRoot.html

- Has AbstractJpaAggregateRootbeen removed?
- Is there any example of using AbstractJpaAggregateRoot and
GenericJpaRepository? It would hekp a lot, as all examples as related
to event-sourced aggregates, none based on AbstractAggregateRoot or
AbstractJpaAggregateRoot.
- What would be the easiest solution to add a command and events based
interface to our system using Axon? Perhaps is there a better
framework for just adding commands and events to a JPA-based
application?

Thanks a lot in advance!!!

The interface we were thinking about for Commands would be something
similar to:

package com.acme.oms.domain;

import com.acme.oms.query.Order;

public class CreateOrderCommand {

  // Let's use the Entity defined on the query package
  // as it will be the classes known by the CRUD interface
  // for creating, updating and deleting.
    private final Order order;

    public CreateOrderCommand(Order order) {
        this.order = order;
    }

  @SuppressWarnings("unused")
  private Order getOrder() {
    return order;
  }

}

Hi Altair,

CQRS is usually not the best choice for a CRUD applications. If you end up with UpdateOrderCommand and CreateOrderCommand that simply contain the updated order, there is not added business value in using CQRS, or Axon. The advantage is when you express what you want changes on the order. Things like ‚ÄúAddProductToOrder‚ÄĚ, ‚ÄúConfirmOrder‚ÄĚ, ‚ÄúShipOrder‚ÄĚ, etc. Have the server (i.e. command handler) make the updates.

Reference to AbstractJpaAggregateRoot should have been removed. My mistake. You can extend AbstractAggregateRoot (or implement the AggregateRoot interface) instead. If you use spring, you can configure the first constructor parameter to be a ContainerManagedEntityManagerProvider.

An example:





About your 20 field question, take into consideration the remark I made about the CRUD style commands. If the 20 blocks really make absolute sense together, then they should be contained in a single command. Quite often, you can see logical groups in these parameters. If that’s the case, you can combine some of them in a value object.

Hope this leads you in the right direction.

Cheers,

Allard