目录
场景简介
1、程序将mybatis框架升级为3.5.9版本 后执行updateByExample
方法时报错
代码片断
java
Condition condition = new Condition(MbCcsSessionConfig.class);
condition.createCriteria().andEqualTo("vdnId", SecurityAuthenUtil.getVdnId());
int row = mbCcsSessionConfigService.updateByExample(param, condition);
实体类
java
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "t_mb_ccs_session_config")
public class MbCcsSessionConfig {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "vdnId")
private Integer vdnId;
@Column(name = "sessionExceptionOverTime")
private Integer sessionExceptionOverTime = 10;
@Column(name = "sessionExceptionAgentOverTime")
private Integer sessionExceptionAgentOverTime = 30;
@Column(name = "sessionExceptionOpenOverTime")
private Integer sessionExceptionOpenOverTime = 20;
@Column(name = "sessionNoStaffOverTime")
private Integer sessionNoStaffOverTime = 5;
@Column(name = "leaveSessionOverTime")
private Integer leaveSessionOverTime = 50;
@Column(name = "leaveAgentOverTime")
private Integer leaveAgentOverTime = 3;
@Column(name = "sessionQueueOverTime")
private Integer sessionQueueOverTime = 60;
@Column(name = "lastUpdateOper")
private String lastUpdateOper;
@Column(name = "lastUpdateDate")
private Date lastUpdateDate;
@Column(name = "leaveSessionAgentOverTime")
private Integer leaveSessionAgentOverTime;
}
报错信息
java
2024-05-22 17:37:20.999 - [DEBUG] - [http-nio-8966-exec-10] - [c.f.m.a.MbCcsSessionConfigMapper.updateByExample - line:137]: ==> Preparing: UPDATE t_mb_ccs_session_config SET vdnId = vdnId,sessionExceptionOverTime = ?,sessionExceptionAgentOverTime = ?,sessionExceptionOpenOverTime = ?,sessionNoStaffOverTime = ?,leaveSessionOverTime = ?,leaveAgentOverTime = ?,sessionQueueOverTime = ?,lastUpdateOper = ?,lastUpdateDate = ?,leaveSessionAgentOverTime = ? WHERE ( ( vdnId = ? ) )
2024-05-22 17:37:21.004 - [DEBUG] - [http-nio-8966-exec-10] - [c.f.m.a.MbCcsSessionConfigMapper.updateByExample - line:137]: ==> Parameters: 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 1(String), 2024-05-22 17:36:42.597(Timestamp), -1(Integer), 1(Integer)
nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: org.apache.shardingsphere.underlying.common.exception.ShardingSphereException: Can not update sharding key, logic table: [t_mb_ccs_session_config], column: [org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment@8348217].
### The error may exist in com/xxx/mapper/admin/MbCcsSessionConfigMapper.java (best guess)
### The error may involve com.xxx.mapper.admin.MbCcsSessionConfigMapper.updateByExample-Inline
### The error occurred while setting parameters
### SQL: UPDATE t_mb_ccs_session_config SET vdnId = vdnId,sessionExceptionOverTime = ?,sessionExceptionAgentOverTime = ?,sessionExceptionOpenOverTime = ?,sessionNoStaffOverTime = ?,leaveSessionOverTime = ?,leaveAgentOverTime = ?,sessionQueueOverTime = ?,lastUpdateOper = ?,lastUpdateDate = ?,leaveSessionAgentOverTime = ? WHERE ( ( vdnId = ? ) )
### Cause: org.apache.shardingsphere.underlying.common.exception.ShardingSphereException: Can not update sharding key, logic table: [t_mb_ccs_session_config], column: [org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment@8348217].
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: org.apache.shardingsphere.underlying.common.exception.ShardingSphereException: Can not update sharding key, logic table: [t_mb_ccs_session_config], column: [org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment@8348217].
### The error may exist in com/xxx/mapper/admin/MbCcsSessionConfigMapper.java (best guess)
### The error may involve com.xxx.mapper.admin.MbCcsSessionConfigMapper.updateByExample-Inline
### The error occurred while setting parameters
### SQL: UPDATE t_mb_ccs_session_config SET vdnId = vdnId,sessionExceptionOverTime = ?,sessionExceptionAgentOverTime = ?,sessionExceptionOpenOverTime = ?,sessionNoStaffOverTime = ?,leaveSessionOverTime = ?,leaveAgentOverTime = ?,sessionQueueOverTime = ?,lastUpdateOper = ?,lastUpdateDate = ?,leaveSessionAgentOverTime = ? WHERE ( ( vdnId = ? ) )
### Cause: org.apache.shardingsphere.underlying.common.exception.ShardingSphereException: Can not update sharding key, logic table: [t_mb_ccs_session_config], column: [org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment@8348217].
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
at com.sun.proxy.$Proxy119.update(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:288)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:67)
at org.apache.ibatis.binding.MapperProxy$PlainMethodInvoker.invoke(MapperProxy.java:145)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86)
at com.sun.proxy.$Proxy246.updateByExample(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:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:241)
at com.sun.proxy.$Proxy247.updateByExample(Unknown Source)
at com.xxx.base.service.impl.BaseServiceImpl.updateByExample(BaseServiceImpl.java:59)
at com.xxx.controller.admin.sysmanager.SysConfigController.saveCcsSessionConfigInfo(SysConfigController.java:261)
at com.xxx.controller.admin.sysmanager.SysConfigController$$FastClassBySpringCGLIB$$c230b3da.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:792)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:707)
at com.xxx.controller.admin.sysmanager.SysConfigController$$EnhancerBySpringCGLIB$$3454dab7.saveCcsSessionConfigInfo(<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:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:111)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:337)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at com.xxx.power.jwt.a.doFilterInternal(JwtAuthenticationTokenFilter.java:212)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:112)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:82)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126)
at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64)
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:367)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:639)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:882)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1647)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:750)
排查
查看报错信息,发现打印出来的SQL有问题,update的部分属性值没有使用占位符?进行占位,而是变成了属性的名称
问题就出现在vdnId = vdnId
,update时,属性值应该像后边的sessionExceptionOverTime 等属性一样,使用?
进行占位的,这里却没有
sql
UPDATE t_mb_ccs_session_config SET vdnId = vdnId,sessionExceptionOverTime = ?,sessionExceptionAgentOverTime = ?,sessionExceptionOpenOverTime = ?,sessionNoStaffOverTime = ?,leaveSessionOverTime = ?,leaveAgentOverTime = ?,sessionQueueOverTime = ?,lastUpdateOper = ?,lastUpdateDate = ?,leaveSessionAgentOverTime = ? WHERE ( ( vdnId = ? ) )
原因
应该是mybatis框架3.5.9版本有与之前的版本有差异导致
解决
测试过程
为什么只有vdnId这个属性有异常,而其他属性却是正常的?
猜测:vdnId是主键,并且存在@Id
注解
如果存在@Id注解的字段都不能参与update?那这个版本的mybatis框架还有使用的价值吗?
-- 测试一:执行其他业务的updateByExample方法
结果:updateByExample执行正常
经过前面的测试,update存在多个条件时,就算更新的字段包含了@Id注解的主键,SQL依旧是正常的
-- 测试二:为原本执行报错的update逻辑多加一个条件
结果:updateByExample执行正常
经过测试,发现在update条件只有主键ID的时候SQL才会出现错误
解决方案
-- 解决方法一:vdnId字段不参与update
结果:updateByExample执行正常
-- 解决方法二:既然想仅仅根据主键ID进行update
,那么可以保留@Id主键,并且使用updateByPrimaryKey方法
结果:updateByExample执行正常
-- 解决方法三:主键ID字段去除@Id注解(不推荐!!!
去掉@Id注解会影响到xxxByPrimaryKey
等方法的使用)
结果:updateByExample执行正常