如何在Quarkus Panache与MongoDB中实现@PrePersist/@PreUpdate?
在MongoDB中自动处理BaseEntity的时间与用户字段
针对你继承ReactivePanacheMongoEntity的BaseEntity,要自动设置createdAt/updatedAt、createdBy/updatedBy,有两种常用方案,对应你在PostgreSQL里用的@PrePersist/@PreUpdate逻辑:
方案一:重写Panache的生命周期回调方法
ReactivePanacheMongoEntity自带预持久化和预更新的回调钩子,直接在BaseEntity里重写即可:
public class BaseEntity extends ReactivePanacheMongoEntity { public ZonedDateTime createdAt; public ZonedDateTime updatedAt; public UUID createdBy; public UUID updatedBy; // 异步获取当前登录用户ID,替换成你的实际实现 private Uni<UUID> getCurrentUserId() { return SecurityContext.getCurrentUser() .map(User::getId) // 假设User实体有getId()返回UUID .onFailure().recoverWithNull(); } @Override public Uni<Void> prePersist() { ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC); createdAt = now; updatedAt = now; return getCurrentUserId() .map(userId -> { createdBy = userId; updatedBy = userId; return null; }) .chain(super::prePersist); } @Override public Uni<Void> preUpdate() { updatedAt = ZonedDateTime.now(ZoneOffset.UTC); return getCurrentUserId() .map(userId -> { updatedBy = userId; return null; }) .chain(super::preUpdate); } }
prePersist:第一次插入实体前触发,初始化创建时间和创建人,同时把更新时间和更新人同步为同一值preUpdate:每次更新实体前触发,更新时间和更新人字段- 注意:Reactive环境下获取用户ID必须用异步方式,避免阻塞事件循环
方案二:使用MongoDB实体监听器
如果想把字段填充逻辑和实体解耦,可自定义监听器:
1. 编写监听器类
public class BaseEntityListener { // 同样实现异步获取当前用户ID的逻辑 private Uni<UUID> getCurrentUserId() { return SecurityContext.getCurrentUser() .map(User::getId) .onFailure().recoverWithNull(); } @PreSave public Uni<Void> onPreSave(BaseEntity entity) { ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC); if (entity.createdAt == null) { // 首次插入,初始化创建相关字段 entity.createdAt = now; return getCurrentUserId() .map(userId -> { entity.createdBy = userId; entity.updatedBy = userId; entity.updatedAt = now; return null; }); } else { // 更新操作,只更新时间和更新人 entity.updatedAt = now; return getCurrentUserId() .map(userId -> { entity.updatedBy = userId; return null; }); } } }
2. 在BaseEntity上绑定监听器
@EntityListeners(BaseEntityListener.class) public class BaseEntity extends ReactivePanacheMongoEntity { public ZonedDateTime createdAt; public ZonedDateTime updatedAt; public UUID createdBy; public UUID updatedBy; }
@PreSave是MongoDB驱动提供的注解,会在每次保存(插入/更新)前触发- 监听器逻辑和实体分离,适合多实体共用同一套字段填充规则的场景
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

