Axon Framework中聚合内部实体的持久化责任及实现方式咨询
在Axon Framework中,聚合内部实体的持久化责任、实现方式完全取决于你选择的聚合存储模式,以下是具体说明:
1 持久化责任划分
- 如果你使用事件溯源模式(Axon官方默认推荐的存储模式):聚合(包括内部所有实体)的持久化完全由框架自动完成,不需要开发人员手动编写数据库操作逻辑。
事件溯源模式下不会直接存储聚合的当前状态,所有状态变更都会以事件的形式存入框架的事件仓库(Event Store),聚合内部的实体状态完全由历史事件溯源重建,不需要单独为实体建表存储当前状态。 - 如果你使用状态存储模式(通用JPA/JDBC聚合存储):开发人员需要自行定义实体的映射规则、级联存储属性,框架仅负责触发聚合根的持久化动作,内部实体的保存由配置的级联规则自动完成,不需要手动写保存逻辑。
2 AddNewBook命令场景的具体实现
2.1 事件溯源模式实现
你只需要完成命令校验、事件发布、聚合状态更新的逻辑即可,不需要手动处理任何持久化操作,示例代码如下:
@Aggregate public class Library { @AggregateIdentifier private String libraryId; private List<Book> books = new ArrayList<>(); // Axon要求的空参构造器 public Library() {} // 处理AddNewBook命令 @CommandHandler public void handle(AddNewBookCommand cmd) { // 自行编写业务校验逻辑,比如ISBN不重复、书名不为空等 apply(new BookAddedEvent( cmd.getLibraryId(), cmd.getBookId(), cmd.getBookName(), cmd.getIsbn() )); } // 事件溯源处理器,更新聚合内部的Book集合 @EventSourcingHandler public void on(BookAddedEvent event) { this.books.add(new Book( event.getBookId(), event.getBookName(), event.getIsbn() )); } }
框架会自动将生成的BookAddedEvent持久化到事件仓库,如果你后续需要查询Book信息,可以单独编写查询端的事件处理器,监听BookAddedEvent后将Book数据存入自定义的查询表即可。
2.2 状态存储模式实现
你需要先给聚合根、内部实体配置JPA注解和级联规则,之后框架会自动完成级联保存,示例代码如下:
@Aggregate @Entity public class Library { @Id @AggregateIdentifier private String libraryId; // 配置级联保存,保存Library时自动保存关联的Book实体 @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) private List<Book> books = new ArrayList<>(); public Library() {} @CommandHandler public void handle(AddNewBookCommand cmd) { // 业务校验逻辑 Book newBook = new Book(cmd.getBookId(), cmd.getBookName(), cmd.getIsbn()); this.books.add(newBook); // 不需要手动调用任何save方法 } } @Entity public class Book { @Id private String bookId; private String bookName; private String isbn; // 构造器、get/set方法省略 }
命令处理完成后,框架会自动持久化Library聚合根,根据你配置的级联规则,新增的Book实体也会自动存入对应的Book数据库表。
3 注意事项
- 不要在聚合的命令处理器中手动注入Repository调用保存方法,两种存储模式下Axon都会自动处理聚合根的持久化,手动调用保存会导致状态不一致。
- 事件溯源模式下事件仓库是唯一的可信数据源,不要直接修改事件仓库的数据,所有聚合状态变更都必须通过发布事件实现。
内容的提问来源于stack exchange,提问作者user1409534
相关产品推荐
相关产品推荐

