Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Axon-聚合的唯一Id是否与实体的唯一Id相同?_Java_Spring Boot_Microservices_Axon - Fatal编程技术网

Java Axon-聚合的唯一Id是否与实体的唯一Id相同?

Java Axon-聚合的唯一Id是否与实体的唯一Id相同?,java,spring-boot,microservices,axon,Java,Spring Boot,Microservices,Axon,我一定是做错了什么 我有一个非常简单的Axon应用程序,它有两个简单的功能:创建一个人并更改此人的姓名 所以我有个人实体: @Entity @Data @NoArgsConstructor public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; } 还有我的人物组合: @Aggregate

我一定是做错了什么

我有一个非常简单的Axon应用程序,它有两个简单的功能:创建一个人并更改此人的姓名

所以我有个人实体:

@Entity
@Data
@NoArgsConstructor
public class Person {    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
}
还有我的人物组合:

@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();
    }

}
这是我的changename命令:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChangeNameCommand {
    @TargetAggregateIdentifier
     private UUID id;
     private String name;    
}
这是我的名字ChangedEvent:

@Value
public class NameChangedEvent {
    private final UUID id;
    private final String name;
}
和存储库:

@Repository
public interface PersonCommandRepository extends JpaRepository<Person, Long> {
}
@存储库
公共接口PersonCommandRepository扩展了JpaRepository{
}
问题是我不确定如何构造我的事件处理程序

@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?
    }
@EventHandler
public void changeName(NameChangedEvent事件){
可选opt=null;//this.personCommandRepository.findById(event.getId());
if(opt.isPresent()){
Person=opt.get();
person.setName(event.getName());
this.personCommandRepository.save(person);//这不是违背了事件来源的目的吗?一点真相?
}
而且,在我的控制器中,我有一个很大的问题,在评论中:

   @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);
    }

}
@RequestMapping(value=“/rename”,method=RequestMethod.POST)
公共响应属性变更名称(@RequestParam(“id”)长id,@RequestParam(“name”)字符串名称){
//1.我们在这里传递哪个Id?聚合还是实体?
//this.commandGateway.send(newchangenamecommand(id,name));
返回新的响应属性(“重命名”,HttpStatus.OK);
}
}

我觉得您仍然在将命令模型和查询模型的概念相互混合

命令模型通常是聚合(或多个),只处理更改某些状态的意向请求。因此,这些意图请求(即命令消息)是针对聚合/命令模型的唯一操作。反之亦然,如果您需要更改某个人的某些内容,则意味着您向
角色聚合
发送一条命令,标记该意图

另一方面,查询模型只负责回答针对应用程序的问题。如果需要知道某人的状态,这意味着您向能够返回您共享的
Person
实体的组件发送查询

回到您描述的“问题”:

  • “这不是违背了事件来源的目的吗?一个单一的真理点?”:事件来源是一个特定于将命令模型从事件本身中重新水化的概念。因此,采用事件源仅意味着您不仅要确定查询模型是通过事件创建的,而且还要确定命令模型。因此,你这样做是在强制执行一个单一的真相来源。因此,使用事件来更新查询模型不会违背ES的目的
  • “我们在这里传递哪个Id?聚合还是实体?”:当你有疑问时,试着找出你想要实现的目标。你在要求提供信息吗?然后是针对您的查询模型的查询。是否打算将某些状态更改为模型?然后向命令模型发送命令。在这种情况下,您需要更改一个人的姓名。因此,可以向聚合/命令模型发送命令
  • AxonIQ的网页上有一个章节描述了所有主要原则。还有一个可能会有所帮助。 可能有助于了解这些信息;可以肯定的是,这些方法可以解决你的很多问题。:-)


    希望这有帮助

    为什么你有两次同样的重演?您的聚合是个人而不是其他JPA实体。@M.Deinum您的意思是我的聚合必须是我的实体吗?像我的存储库一样,我的存储库是
    PersonCommandRepository扩展了JpaRepository
    ?否。聚合是
    。那是你的图思之源。您不需要实体(根据您自己的评论/问题判断,实体已经在那里闪耀了)。@M.Deinum好的,那么我的存储库会是什么样子呢?我不确定,你可以通过修改代码和作为答案发布来帮助我。为了什么?它处理一个请求,创建一个命令并将其发送给axon。对于一个查询,它也会这样做,但对于查询部分,可能是在实体的投影上。所有这些都在axon手册和示例/教程中进行了解释。我强烈建议你按照这些去做,而不是自己去想办法。谢谢你,史蒂文,是的,我一直在把事情混在一起!我刚看完你2017年的演讲,基辅&我正在打开我的电子邮件,看到你的回复。是的,“观点-演讲观点和会议观点”让我走上了正确的方向!让我看看链接的材料,肯定会有帮助!很高兴听到这一点,但我在基辅的录音也帮助你们理解了这一切!:-)