【转】Interceptor 中onFlushDirty()函数执行多次的问题(Hibernate 的一个小Bug)

本文解决使用Hibernate拦截器时,onFlushDirty()函数执行多次导致实体变化产生重复数据的问题。通过调整FlushMode为COMMIT或提前调用flush()方法,可以有效解决此问题。

最近在项目中遇到一个奇怪的问题,在使用Hibernate拦截器捕获实体变化并进行处理时,发现其中的onFlushDirty()函数执行了很多次,导致进行处理时产生很多重复数据。具体问题如下:
使用一个类继承Hibernate的HistoryInterceptor类来对程序中的实体变化进行拦截,并在其中的onFlushDirty()函数中对捕获的数据进行处理,产生对应的event数据并保存到数据库中。 例如:
public class EventInterceptor extends EmptyInterceptor {
public boolean onFlushDirty(
        Object entity,
        Serializable id,
        Object[] currentState,
        Object[] previousState,
        String[] propertyNames,
        Type[] types ) throws CallbackException {

        if(isAuditable(entity)){//如果该实体需要被记录,生成对应的event。
            //此处生成对应的event。
        }
        return false;
    }

在程序执行后,发现对应一条实体的变化生成了多条重复的event记录,非常不解。
后来google发现,有人也碰到过对应的问题,并在Hibernage论坛中提出过这个问题,鉴定为Hibernate的一个小Bug。
(原文地址:http://forum.hibernate.org/viewtopic.php?t=940410&highlight=interceptor+onflushdirty)
解决方法如下:
将FlushMode改为:FlushMode.COMMIT
或者也可以提前进行flush()
都可以解决这个问题。

在 gRPC 中,`withInterceptors()` 方法多次调用且每次传入相同的拦截器(Interceptor),会导致该拦截器在调用链中被多次添加,从而在每次 RPC 调用时,该拦截器的逻辑会被重复执行。 `withInterceptors()` 方法的设计允许在客户端或服务器构建时添加多个拦截器,每次调用该方法都会将传入的拦截器添加到已有的拦截器列表中。因此,当多次传入相同的拦截器时,该拦截器会在调用链中出现多次。 以下是一个简单的 Java 代码示例,展示了多次调用 `withInterceptors()` 方法并传入相同拦截器的情况: ```java import io.grpc.*; class CustomInterceptor implements ClientInterceptor { @Override public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) { System.out.println("Interceptor logic executed"); return next.newCall(method, callOptions); } } public class GrpcInterceptorExample { public static void main(String[] args) { CustomInterceptor interceptor = new CustomInterceptor(); ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051) .usePlaintext() .intercept(interceptor) // 第一次添加拦截器 .intercept(interceptor) // 第二次添加相同的拦截器 .build(); // 进行 RPC 调用 // ... channel.shutdown(); } } ``` 在上述示例中,`CustomInterceptor` 被两次添加到客户端的调用链中。当进行 RPC 调用时,`Interceptor logic executed` 会被打印两次,说明拦截器的逻辑被重复执行。 这种行为可能会导致一些问题,例如不必要的性能开销,因为相同的逻辑会被多次执行;还可能导致逻辑异常,例如计数器或状态管理逻辑被多次执行,从而产生错误的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值