解决updateByExample时属性值异常的问题(部分属性值没有使用占位符?进行占位,而是变成了属性的名称)

目录


场景简介

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执行正常

相关推荐
喵叔哟8 分钟前
重构代码之移动字段
java·数据库·重构
喵叔哟8 分钟前
重构代码之取消临时字段
java·前端·重构
fa_lsyk10 分钟前
maven环境搭建
java·maven
Daniel 大东30 分钟前
idea 解决缓存损坏问题
java·缓存·intellij-idea
wind瑞36 分钟前
IntelliJ IDEA插件开发-代码补全插件入门开发
java·ide·intellij-idea
HappyAcmen36 分钟前
IDEA部署AI代写插件
java·人工智能·intellij-idea
马剑威(威哥爱编程)42 分钟前
读写锁分离设计模式详解
java·设计模式·java-ee
鸽鸽程序猿42 分钟前
【算法】【优选算法】前缀和(上)
java·算法·前缀和
修道-032343 分钟前
【JAVA】二、设计模式之策略模式
java·设计模式·策略模式
九圣残炎1 小时前
【从零开始的LeetCode-算法】2559. 统计范围内的元音字符串数
java·算法·leetcode