Hibernate 6与5中@Filter注解行为差异及兼容方案咨询
Hibernate 5 vs 6 @Filter 行为差异及兼容方案
版本差异点
Hibernate 6.1.x 对实体过滤器的生效逻辑做了核心调整:
- Hibernate 5.6:启用的过滤器仅作用于显式查询的主实体,关联实体的懒加载查询不会自动继承过滤器条件。所以查询
Entity1时,懒加载关联的Staff不会带上DELETED=0过滤条件。 - Hibernate 6.1:默认会将启用的过滤器自动应用到所有标注了该过滤器的实体查询中,包括关联实体的懒加载查询。因此加载
Staff时会自动追加DELETED=0条件,这是Hibernate 6为统一过滤器作用范围做出的设计变更。
兼容Hibernate 5行为的解决方案
方案1:针对关联关系精准禁用过滤器
在Entity1的staff字段上,通过@Filter注解的disableFilters属性,指定懒加载该关联时禁用notDeleted过滤器:
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "StaffID") @Filter(name = "notDeleted", disableFilters = "notDeleted") private Staff staff;
这种方式仅影响当前关联的过滤器行为,不会干扰其他实体的过滤器生效逻辑。
方案2:全局配置回退到Hibernate 5逻辑
通过Hibernate配置属性,全局关闭过滤器自动应用到关联查询的特性:
- 若使用
application.properties或hibernate.properties:
hibernate.filter.auto_apply_to_joins=false
- 若使用
persistence.xml:
<property name="hibernate.filter.auto_apply_to_joins" value="false"/>
配置后,所有关联实体的懒加载查询都不会自动继承启用的过滤器,完全对齐Hibernate 5的行为。
方案3:临时手动控制过滤器状态
在需要加载Staff的代码块中,临时禁用过滤器,加载完成后恢复:
var entity = getSession().createQuery("from Entity1 where id = :id", Entity1.class) .setParameter("id", 18874846) .uniqueResult(); Session session = getCurrentSession(); // 临时禁用notDeleted过滤器 session.disableFilter("notDeleted"); // 触发懒加载 Staff staff = entity.getStaff(); // 重新启用过滤器 session.enableFilter("notDeleted"); assertNotNull(staff); assertThat(staff.getDeleted()).isNotZero();
该方式适合局部特殊场景,但代码侵入性较强,不推荐全局使用。
内容的提问来源于stack exchange,提问作者Bogdan Marinescu
相关产品推荐
相关产品推荐

