如何在OpenXava中实现软删除策略?
在OpenXava中实现软删除策略
OpenXava确实没有内置软删除(通过deletedAt时间标记而非物理删除)的实现,但可以通过以下步骤快速搭建这套逻辑,适配企业级场景中保留数据、默认过滤已删除记录的需求:
1. 给实体添加软删除字段
在需要软删除的实体类中,新增deletedAt字段,用于标记删除时间,默认值为null(未删除状态)。通过@Hidden注解在默认视图中隐藏该字段,避免干扰日常操作:
import javax.persistence.*; import java.time.LocalDateTime; import org.openxava.annotations.*; @Entity public class YourEntity { // 替换为你的实体类名 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 你的业务字段... @Column(name = "deleted_at") @Hidden // 在默认视图中隐藏,仅在恢复操作时使用 private LocalDateTime deletedAt; // Getter & Setter public LocalDateTime getDeletedAt() { return deletedAt; } public void setDeletedAt(LocalDateTime deletedAt) { this.deletedAt = deletedAt; } }
2. 重写删除逻辑,替换为软删除标记
通过OpenXava的@OnDelete注解,指定自定义处理器,将默认的物理删除改为设置deletedAt为当前时间:
第一步:给实体类添加注解
@Entity @OnDelete(handler = SoftDeleteHandler.class) // 指定软删除处理器 public class YourEntity { // ... 实体字段 }
第二步:实现软删除处理器
import org.openxava.actions.*; import org.openxava.jpa.*; import java.time.LocalDateTime; public class SoftDeleteHandler extends OnDeleteHandlerBase { @Override public void execute() throws Exception { // 获取待删除的实体对象 YourEntity entity = (YourEntity) getView().getEntity(); // 设置删除时间 entity.setDeletedAt(LocalDateTime.now()); // 执行更新而非删除 XPersistence.getManager().merge(entity); // 提示操作成功 addMessage("soft_delete_success", entity.getClass().getSimpleName()); // 刷新视图移除当前行 getView().setEntity(null); getView().refresh(); } }
3. 全局过滤已删除数据
通过@Where注解给实体添加默认查询条件,让所有默认列表、查询操作自动排除已删除的记录:
@Entity @OnDelete(handler = SoftDeleteHandler.class) @Where(clause = "deleted_at is null") // 仅查询未删除的实体 public class YourEntity { // ... 实体字段 }
4. 可选:添加恢复已删除实体的功能
如果需要恢复误删的数据,可以自定义恢复动作:
第一步:在视图配置中添加恢复按钮
在实体对应的views.xml的列表视图中添加恢复动作:
<view name="List"> <actions> <action name="restore" class="com.yourcompany.yourapp.actions.RestoreEntityAction" /> </actions> <!-- 你的列定义 --> </view>
第二步:实现恢复动作类
import org.openxava.actions.*; import org.openxava.jpa.*; import java.util.Collection; public class RestoreEntityAction extends ViewBaseAction { @Override public void execute() throws Exception { // 获取选中的已删除实体 Collection<YourEntity> selectedEntities = getView().getSelectedObjects(); for (YourEntity entity : selectedEntities) { entity.setDeletedAt(null); // 清除删除标记 XPersistence.getManager().merge(entity); } addMessage("restore_success", selectedEntities.size()); getView().refresh(); } }
注意事项
- 关联实体:如果实体存在关联关系,需在关联字段上添加
@Where(clause = "deleted_at is null"),避免查询出已删除的关联数据。 - 权限控制:物理删除动作可单独实现,仅开放给特定权限的管理员使用。
- 日志审计:可在软删除处理器中添加日志记录逻辑,追踪删除操作的发起者和时间。
内容的提问来源于stack exchange,提问作者Lucio Crusca
相关产品推荐
相关产品推荐

