如何为AnyMetaDef的targetEntity添加过滤条件排除软删除数据?
解决方案:解决@Any关联无法识别@Where过滤已删除数据的问题
以下是几种可行的处理方式,你可以根据自身场景选择:
1. 在@Any关联字段上直接添加@Where注解
尝试在item字段上追加@Where注解,直接指定过滤条件:
@Any(metaColumn = @Column(name = "ITEM_TYPE"),fetch = FetchType.LAZY) @AnyMetaDef(idType = "long", metaType = "string", metaValues = { @MetaValue(targetEntity = Book.class, value = "B"), @MetaValue(targetEntity = VHS.class, value = "V"), @MetaValue(targetEntity = DVD.class, value = "D") }) @JoinColumn(name="ITEM_ID", insertable = false, updatable = false) @Where(clause = "status != 'DELETED'") private Object item;
该方式直接针对关联的目标表添加过滤逻辑,Hibernate加载关联数据时会自动拼接此条件。
2. 使用Hibernate Filter全局过滤已删除数据
步骤1:定义Filter规则
在包含@Any关联的实体类上定义过滤规则:
@Entity @FilterDef(name = "excludeDeletedItems", parameters = @ParamDef(name = "deletedStatus", type = "string")) public class YourEntity { // 替换为你实际的实体类名 @Any(...) // 保留原有的@Any及相关注解 @JoinColumn(...) @Filter(name = "excludeDeletedItems", condition = "status != :deletedStatus") private Object item; // 其他字段、构造方法及Getter/Setter }
步骤2:查询时启用Filter
执行查询前,通过Session或EntityManager启用Filter并设置参数:
// Session方式 session.enableFilter("excludeDeletedItems").setParameter("deletedStatus", "DELETED"); // EntityManager方式 entityManager.unwrap(Session.class).enableFilter("excludeDeletedItems").setParameter("deletedStatus", "DELETED");
这种方式适合需要动态控制过滤逻辑的场景,比如特殊查询需查看已删除数据时,可临时关闭Filter。
3. 在JPQL/HQL查询中显式添加过滤条件
若注解方式不生效,可在查询语句中手动过滤已删除数据:
SELECT e FROM YourEntity e WHERE (TYPE(e.item) = Book AND e.item.status != 'DELETED') OR (TYPE(e.item) = VHS AND e.item.status != 'DELETED') OR (TYPE(e.item) = DVD AND e.item.status != 'DELETED')
通过TYPE()函数区分不同实体类型,再分别添加status过滤条件,确保仅查询未删除的关联数据。
4. 统一父类+继承共享@Where注解
定义包含status字段和@Where注解的父类,让Book、VHS、DVD继承该类,同时修改@Any的关联类型为父类:
步骤1:定义父类
@MappedSuperclass @Where(clause = "status != 'DELETED'") public abstract class AbstractItem { @Column(name = "status") private String status; // Getter和Setter方法 }
步骤2:实体类继承父类
@Entity public class Book extends AbstractItem { // Book专属字段与方法 } // VHS、DVD同理,继承AbstractItem
步骤3:修改@Any关联类型
@Any(metaColumn = @Column(name = "ITEM_TYPE"),fetch = FetchType.LAZY) @AnyMetaDef(idType = "long", metaType = "string", metaValues = { @MetaValue(targetEntity = Book.class, value = "B"), @MetaValue(targetEntity = VHS.class, value = "V"), @MetaValue(targetEntity = DVD.class, value = "D") }) @JoinColumn(name="ITEM_ID", insertable = false, updatable = false) private AbstractItem item;
这种方式通过继承让所有子实体共享@Where过滤规则,同时@Any关联父类类型,Hibernate会自动应用父类的@Where条件。
内容的提问来源于stack exchange,提问作者JuniorDev
相关产品推荐
相关产品推荐

