如何自定义org.hibernate.query.Query的executeUpdate实现,增加前后置逻辑
方案1:自定义统一执行工具类 + 静态检查拦截原生调用
无需扩展Hibernate的Session、Query类,原有构造查询的逻辑完全不变,仅替换最终执行步骤为自定义方法即可,全程保留IDE的HQL/SQL校验能力。
自定义工具类实现示例:
public class HibernateUpdateExecutor { public static int executeUpdate(Query<?> query) { // 自定义前置逻辑,如参数校验、操作审计、权限校验等 doBeforeUpdate(); int affectedRows = query.executeUpdate(); // 自定义后置逻辑,如缓存刷新、事件推送等 doAfterUpdate(); return affectedRows; } private static void doBeforeUpdate() { // 前置逻辑实现 } private static void doAfterUpdate() { // 后置逻辑实现 } }
业务代码仅需修改最后一行执行逻辑:
public void updateMyClass (String value) { Session session = sessionFactory.getCurrentSession(); Query<Void> query = session .createQuery("UPDATE MyClass SET value = :value ") .setParameter("value", value); // 替换原生调用为自定义工具方法 HibernateUpdateExecutor.executeUpdate(query); }
拦截原生调用的方式:在IDE(如IDEA)的检查规则中添加禁止调用项org.hibernate.query.Query#executeUpdate,设置为报错级别,直接调用原生方法时会实时标红提示;团队协作场景可同步配置SonarQube等静态检查规则,在CI/CD阶段拦截违规提交。
方案2:AOP切面拦截原生方法(零业务代码侵入)
如果不想修改现有业务代码,可直接用AspectJ切面拦截executeUpdate方法的执行,在环绕通知中嵌入前后置逻辑,全程使用Hibernate原生类,完全不影响IDE的语法校验能力。
切面实现示例:
@Aspect public class HibernateUpdateAspect { @Around("execution(* org.hibernate.query.Query.executeUpdate(..))") public Object aroundExecuteUpdate(ProceedingJoinPoint joinPoint) throws Throwable { // 前置逻辑 doBeforeUpdate(); Object result = joinPoint.proceed(); // 后置逻辑 doAfterUpdate(); return result; } // 前后置逻辑实现同上 }
如果使用Spring框架,只需将该切面注册到Spring上下文即可生效;非Spring场景可使用AspectJ编译时织入能力实现全局拦截。
内容的提问来源于stack exchange,提问作者Shai Givati
相关产品推荐
相关产品推荐

