Spring Data JDBC中非聚合实体的生命周期事件未触发问题
Spring Data JDBC关联实体生命周期事件不触发的问题解决
问题背景
使用Employee和Address两个实体,Employee具备CRUD控制器,为两者配置生命周期事件后,Employee的事件可正常触发,但Address的事件无法触发。保存包含Address的Employee(一对一关联)时,期望两者的生命周期事件均能触发,且数据已正常保存,Spring Data JDBC的一对一关联未添加额外注解。
问题原因
Spring Data JDBC中,聚合根(此处为Employee)的关联子实体(Address)不会自动触发自身的生命周期事件——框架将子实体视为聚合根的一部分,仅针对聚合根发布事件,不会单独为子实体发布事件。
解决方案
可以在聚合根的事件监听器中,手动获取子实体,并通过ApplicationEventPublisher发布子实体对应的生命周期事件,具体代码修改如下:
修改EmployeeEvents类
@Component public class EmployeeEvents extends AbstractRelationalEventListener<Employee> { private final ApplicationEventPublisher eventPublisher; // 构造注入事件发布器 public EmployeeEvents(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } @Override protected void onBeforeSave(BeforeSaveEvent<Employee> event) { System.out.println("........" + event.getEntity()); // 获取关联的Address,存在则发布对应的BeforeSaveEvent Employee employee = event.getEntity(); Address address = employee.getAddress(); if (address != null) { BeforeSaveEvent<Address> addressEvent = new BeforeSaveEvent<>(address, event.getAggregateChange()); eventPublisher.publishEvent(addressEvent); } } }
这样当Employee的BeforeSaveEvent触发时,会同步发布Address的BeforeSaveEvent,AddressEvents中的方法就能正常执行。
可选方案:调整聚合边界
如果业务上需要Address作为独立聚合根存在,可将Employee中的Address关联改为@Reference注解,此时需要分别保存Address和Employee,Address的事件会自动触发,但这种方式会改变数据模型的聚合边界,需根据业务场景判断是否适用。
内容的提问来源于stack exchange,提问作者Ravi
相关产品推荐
相关产品推荐

