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