-
-
Couldn't load subscription status.
- Fork 3.1k
Closed
Description
- 我已在 issues 搜索类似问题,并且不存在相同的问题.
异常模板
使用环境
- PageHelper 版本: 5.1.10
- 数据库类型和版本: 5.7.26-30102-log
- JDBC_URL: jdbc:mysql://xx.xx.xx:3306/xxdb?characterEncoding=UTF8&socketTimeout=60000&allowMultiQueries=true
完整异常信息
[Encrypt]【查询员工信息】param:{"type":"id","ids":[2481818508],"entId":5472009}
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.NullPointerException
### Cause: java.lang.NullPointerException
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy185.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:230)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:139)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:76)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
at com.sun.proxy.$Proxy191.queryByCondition(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.xxx.dao.AsyncMapperProxy.invoke(AsyncMapperProxy.java:67)
at com.sun.proxy.$Proxy191.queryByCondition(Unknown Source)
at com.xxx.yyy.service.inner.impl.EmployInfoServiceImpl.queryByCondition(EmployInfoServiceImpl.java:346)
at com.xxx.yyy.service.inner.impl.EmployInfoServiceImpl$$FastClassBySpringCGLIB$$3f507d61.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
at com.xxx.yyy.service.inner.impl.EmployInfoServiceImpl$$EnhancerBySpringCGLIB$$50a1d81a.queryByCondition(<generated>)
at com.xxx.yyy.server.thrift.EmployInfoThriftServiceImpl.queryByCondition(EmployInfoThriftServiceImpl.java:444)
at com.xxx.yyy.server.thrift.EmployInfoThriftServiceImpl$$FastClassBySpringCGLIB$$87624c37.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:736)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671)
at com.xxx.yyy.server.thrift.EmployInfoThriftServiceImpl$$EnhancerBySpringCGLIB$$587ebeef.queryByCondition(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.xxx.service.mobile.thrift.proxy.ThriftServerInvoker.doInvoke(ThriftServerInvoker.java:363)
at com.xxx.service.mobile.thrift.proxy.ThriftServerInvoker$1.handle(ThriftServerInvoker.java:389)
at com.xxx.service.mobile.thrift.server.filter.AccessLogFilter.filter(AccessLogFilter.java:39)
at com.xxx.dorado.rpc.handler.filter.InvokeChainBuilder$2.handle(InvokeChainBuilder.java:106)
at com.xxx.service.mobile.thrift.server.filter.ServerRhinoLimiterFilter.filter(ServerRhinoLimiterFilter.java:73)
at com.xxx.dorado.rpc.handler.filter.InvokeChainBuilder$2.handle(InvokeChainBuilder.java:106)
at com.xxx.service.mobile.thrift.proxy.ThriftServerInvoker.invoke(ThriftServerInvoker.java:304)
at com.sun.proxy.$Proxy285.queryByCondition(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.xxx.service.mobile.thrift.annotation.ThriftMethodProcessor.invokeMethod(ThriftMethodProcessor.java:174)
at com.xxx.service.mobile.thrift.annotation.ThriftMethodProcessor.process(ThriftMethodProcessor.java:138)
at com.xxx.service.mobile.thrift.proxy.ThriftServerPublisher$ThriftServiceProcessor.process(ThriftServerPublisher.java:642)
at com.xxx.service.mobile.thrift.server.netty.DefaultServerHandler.handleRequest(DefaultServerHandler.java:273)
at com.xxx.service.mobile.thrift.server.netty.DefaultServerHandler$1.run(DefaultServerHandler.java:164)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.NullPointerException
### Cause: java.lang.NullPointerException
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
... 54 more
Caused by: java.lang.NullPointerException
at com.github.pagehelper.PageHelper.afterAll(PageHelper.java:118)
at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:113)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
at com.sun.proxy.$Proxy337.query(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
... 60 more
原因
PageInterceptor类对象里面会初始化PageHelper(对应变量dialect);
PageHelper类对象里面会初始化PageAutoDialect(对应变量autoDialect);
1.由于采用的都是单例模式,服务启动时,假定有2个线程进入分页查询场景,分别是线程A和B;
2.当线程A执行至初始化完PageHelper(dialect变量不为null),而PageHelper类尚未初始化完成(对应autoDialect变量);
3.线程B执行至以下代码时,由于dialect不为null,所以跳过,执行后续业务逻辑;
private void checkDialectExists() {
if (dialect == null) {
synchronized (default_dialect_class) {
if (dialect == null) {
setProperties(new Properties());
}
}
}
}
4.当线程B执行至dialect.afterAll();这里,但线程A尚未初始化完PageHelper类时,就会出现NPE异常
功能建议
确保pageHelper.autoDialect变量初始化成功
private void checkDialectExists() {
if (dialect == null || pageHelper.autoDialect == null) {
synchronized (default_dialect_class) {
if (dialect == null || pageHelper.autoDialect == null {
setProperties(new Properties());
}
}
}
}
Metadata
Metadata
Assignees
Labels
No labels