Аксон - Является ли уникальный идентификатор моего Агрегата равным / таким же, как у моей сущности? - PullRequest
0 голосов
/ 19 марта 2020

Я, должно быть, здесь что-то делаю не так.

У меня есть очень простое приложение Axon, которое имеет две простые функции: создать человека и изменить имя человека .

Итак, у меня есть Person Entity:

@Entity
@Data
@NoArgsConstructor
public class Person {    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
}

И мой PersonAggregate:

@Aggregate
@Data
@NoArgsConstructor
public class PersonAggregate {

    @AggregateIdentifier
    private UUID id;
    private String name;


    @CommandHandler
    public PersonAggregate(CreatePersonCommand command) {
        apply(new PersonCreatedEvent(
                command.getId(),
                command.getName()
        ));
    }

    @EventSourcingHandler
    public void on(PersonCreatedEvent event) {
        this.id = event.getId();
        this.name = event.getName();
    }

    @CommandHandler
    public void handle(ChangeNameCommand command) {
        apply(
                new NameChangedEvent(
                        command.getId(),
                        command.getName()
                )
        );
    }

    @EventSourcingHandler
    public void on(NameChangedEvent event) {
        this.name = event.getName();
    }

}

И это мой ChangeNameCommand:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChangeNameCommand {
    @TargetAggregateIdentifier
     private UUID id;
     private String name;    
}

И это мой NameChangedEvent:

@Value
public class NameChangedEvent {
    private final UUID id;
    private final String name;
}

и репозиторий:

@Repository
public interface PersonCommandRepository extends JpaRepository<Person, Long> {
}

Проблема заключается в том, что я не уверен, как структурировать мой обработчик событий

@EventHandler
public void changeName(NameChangedEvent event) {
    Optional<Person> opt = null;//this.personCommandRepository.findById(event.getId());
    if (opt.isPresent()) {
        Person person = opt.get();
        person.setName(event.getName());
        this.personCommandRepository.save(person); //Does'nt this defeat the purpose of Event Sourcing? A single point of truth?
    }

А также, в моем контроллере у меня довольно большая проблема, в комментарии:

   @RequestMapping(value = "/rename", method = RequestMethod.POST)
    public ResponseEntity<?> changeName(@RequestParam("id") Long id, @RequestParam("name")String name){
        //1. Which Id do we pass in here? Aggregate or Entity?
        //this.commandGateway.send(new ChangeNameCommand(id,name));
        return new ResponseEntity<String>("Renamed", HttpStatus.OK);
    }

}

1 Ответ

1 голос
/ 20 марта 2020

Я чувствую, что вы все еще смешиваете идею Командной модели и Модели запросов друг с другом.

Модель команд, которая обычно представляет собой совокупность (или несколько), обрабатывает только запросов на намерение изменить какое-либо состояние . Таким образом, эти запросы намерения, то есть командное сообщение, являются единственными операциями, нацеленными на вашу модель совокупности / команд. И наоборот, если у вас есть требование что-то изменить в Person, это означает, что вы отправляете команду с пометкой, предназначенной для PersonAggregate.

Модель запроса, с другой стороны, предназначена исключительно для ответа на вопросы. ориентированы на ваше приложение. Если необходимо как-то узнать состояние человека, это означает, что вы отправляете запрос компоненту, способному возвратить Person сущность, которой вы поделились.

Возвращаясь к описанным вами «проблемам» :

  1. «Разве это не противоречит цели поиска событий? Единственная точка правды?» : Источник событий - это концепция, определяющая c в направлении регидратации модель команды из событий сама опубликовала. Таким образом, использование Event Sourcing просто означает, что вы уверены, что не только ваши модели запросов создаются посредством событий, но и ваши модели команд. Эх go, вы делаете это одним источником правды. Использование событий для обновления моделей запросов, таким образом, не не наносит ущерба цели ES.
  2. «Какой идентификатор мы здесь передаем? Агрегат или сущность?» : Когда Вы сомневаетесь, попытайтесь выяснить, чего вы хотите достичь. Вы запрашиваете информацию? Тогда это запрос, направленный на вашу модель запроса. Намерен ли изменить какое-то состояние на модель? Затем вы отправляете команду в направлении модели команд. В этом точном сценарии вы хотите изменить имя человека. Таким образом, вы отправляете команду в агрегатную / командную модель.

На веб-странице AxonIQ есть раздел Архитектурные концепции , описывающий все основные принципы. Также есть одна информация о CQRS , которая может помочь. Может помочь прочитать об этом; Я уверен, что многие из них решат многие ваши вопросы. : -)

Надеюсь, это поможет!

...