Spring Boot中如何对外部依赖的实体类使用@Where注解
解决方案
针对外部依赖包的实体无法直接加@Where注解的场景,有两种可落地的实现方案:
方案1:继承外部实体,在子类上加注解
在本地项目中创建外部实体的子类,在子类上标注@Where注解,后续所有持久层操作统一使用该子类即可:
// 外部依赖包中不可修改的原有实体 package com.external.project; @Entity public class ExternalUser { @Id private Long id; private Integer isDeleted; // 其他原有字段、方法 } // 本地项目自定义的子类 package com.your.project; @Entity @Where(clause = "is_deleted = 0") public class LocalExternalUser extends ExternalUser { // 无需额外新增字段,直接继承父类所有属性即可 }
适用场景:需要灵活切换过滤规则、或需要对原有实体做字段扩展的场景。
注意事项:如果原有业务代码已经大量引用了外部实体,需要统一替换为子类引用。
方案2:启动时动态给外部实体添加全局过滤规则
通过Hibernate的Integrator扩展点,在SessionFactory初始化时直接给外部实体绑定过滤条件,效果和直接在实体上标注@Where完全一致,无需修改原有业务代码:
import org.hibernate.boot.Metadata; import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.SessionFactoryImplementor; import org.hibernate.integrator.spi.Integrator; import org.hibernate.mapping.PersistentClass; import org.hibernate.service.spi.SessionFactoryServiceRegistry; import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; import org.springframework.stereotype.Component; import java.util.Collections; import java.util.Map; @Component public class ExternalEntityWhereConfig implements HibernatePropertiesCustomizer { @Override public void customize(Map<String, Object> hibernateProperties) { hibernateProperties.put("hibernate.integrator_provider", (IntegratorProvider) () -> Collections.singletonList(new WhereInjectIntegrator())); } static class WhereInjectIntegrator implements Integrator { @Override public void integrate(Metadata metadata, BootstrapContext bootstrapContext, SessionFactoryImplementor sessionFactory) { // 绑定外部实体的全局where条件 PersistentClass externalEntityMeta = metadata.getEntityBinding(ExternalUser.class.getName()); // 这里的clause和@Where注解的参数规则完全一致 externalEntityMeta.setWhere("is_deleted = 0"); } @Override public void disintegrate(SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) {} } }
适用场景:不想修改原有业务代码、需要全局生效的场景,也是最推荐的实现方式。
注意:Hibernate 6开始@Where注解被标记为废弃,该方案依然兼容,也可以直接用动态注册过滤器的方式替代,效果一致。
内容的提问来源于stack exchange,提问作者SBDev
相关产品推荐
相关产品推荐

