Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[错误报告]: mybatis-plus 3.5.7-3.5.10.1版本 pgsql 主键是UUID 执行removeByIds removeBatchByIds方法时报错 #6677

Open
3 tasks done
zijun-hiwintech opened this issue Jan 22, 2025 · 4 comments

Comments

@zijun-hiwintech
Copy link

确认

  • 我使用的版本是最新版, 并且使用插件确认过项目里无依赖版本冲突
  • 我已经在 issue 中搜索过, 确认问题没有被提出过
  • 我已经修改标题, 将标题中的 描述 替换为遇到的问题

当前程序版本

3.5.7-3.5.10.1

问题描述

执行环境 spring boot 3.3.7 版本 pgsql16.3 主键是UUID 执行removeByIds removeBatchByIds方法时报错
之前的mybatis 3.5.6 执行正常而升级之后的3.5.7-3.5.10.1 执行相关方法报错

List ids = List.of(UUID.fromString("688aa547-09f8-4a26-8c71-411d4ba7d67e"));
boolean flag = sysUserTokenService.removeByIds(List.of(ids));

org.mybatis.spring.MyBatisSystemException:

Error updating database. Cause: java.lang.UnsupportedOperationException

The error may exist in system/mapper/SysUserTokenMapper.java (best guess)

The error may involve system.mapper.SysUserTokenMapper.deleteByIds

The error occurred while executing an update

Cause: java.lang.UnsupportedOperationException

详细堆栈日志

org.mybatis.spring.MyBatisSystemException: 
### Error updating database.  Cause: java.lang.UnsupportedOperationException
### The error may exist in /system/mapper/SysUserTokenMapper.java (best guess)
### The error may involve system.mapper.SysUserTokenMapper.deleteByIds
### The error occurred while executing an update
### Cause: java.lang.UnsupportedOperationException

	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:99)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:347)
	at jdk.proxy2/jdk.proxy2.$Proxy153.delete(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.delete(SqlSessionTemplate.java:244)
	at com.baomidou.mybatisplus.core.mapper.BaseMapper.deleteByIds(BaseMapper.java:219)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:166)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
	at jdk.proxy2/jdk.proxy2.$Proxy178.deleteByIds(Unknown Source)
	at com.baomidou.mybatisplus.core.mapper.BaseMapper.deleteByIds(BaseMapper.java:185)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:166)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
	at jdk.proxy2/jdk.proxy2.$Proxy178.deleteByIds(Unknown Source)
	at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.removeBatchByIds(ServiceImpl.java:302)
	at com.baomidou.mybatisplus.extension.service.IService.removeBatchByIds(IService.java:186)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720)
	at system.service.impl.SysUserTokenServiceImpl$$SpringCGLIB$$0.removeBatchByIds(<generated>)
	at test.DemoTest.test3(DemoTest.java:21)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: java.lang.UnsupportedOperationException
### The error may exist in system/mapper/SysUserTokenMapper.java (best guess)
### The error may involve system.mapper.SysUserTokenMapper.deleteByIds
### The error occurred while executing an update
### Cause: java.lang.UnsupportedOperationException
	at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:199)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:212)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:333)
	... 32 more
Caused by: java.lang.UnsupportedOperationException
	at org.apache.ibatis.reflection.wrapper.CollectionWrapper.hasGetter(CollectionWrapper.java:78)
	at org.apache.ibatis.reflection.MetaObject.hasGetter(MetaObject.java:110)
	at org.apache.ibatis.reflection.wrapper.MapWrapper.hasGetter(MapWrapper.java:128)
	at org.apache.ibatis.reflection.MetaObject.hasGetter(MetaObject.java:110)
	at org.apache.ibatis.builder.SqlSourceBuilder$ParameterMappingTokenHandler.buildParameterMapping(SqlSourceBuilder.java:97)
	at org.apache.ibatis.builder.SqlSourceBuilder$ParameterMappingTokenHandler.handleToken(SqlSourceBuilder.java:89)
	at org.apache.ibatis.parsing.GenericTokenParser.parse(GenericTokenParser.java:76)
	at org.apache.ibatis.builder.SqlSourceBuilder.parse(SqlSourceBuilder.java:51)
	at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:42)
	at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:320)
	at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:65)
	at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:42)
	at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:47)
	at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:719)
	at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
	at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
	at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:61)
	at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:106)
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59)
	at jdk.proxy2/jdk.proxy2.$Proxy198.update(Unknown Source)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197)
	... 38 more
@zijun-hiwintech
Copy link
Author

另外 我的实体类主键是UUID
@TableName(value = "sys_user_token")
public class SysUserToken extends BaseModel {

@Serial
private static final long serialVersionUID = 1L;
@TableId(value = "id",type = IdType.INPUT)
private UUID id;

}
切换到3.5.8 报错信息如下:

org.mybatis.spring.MyBatisSystemException:

Error updating database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.util.UUID'

The error may exist in system/mapper/SysUserTokenMapper.java (best guess)

The error may involve system.mapper.SysUserTokenMapper.deleteByIds-Inline

The error occurred while setting parameters

SQL: UPDATE sys_user_token SET updated_at=?,updated_by=?, is_deleted=true WHERE id IN ( ? ) AND is_deleted=false

Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.util.UUID'

at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:99)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:347)
at jdk.proxy2/jdk.proxy2.$Proxy151.delete(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.delete(SqlSessionTemplate.java:244)
at com.baomidou.mybatisplus.core.mapper.BaseMapper.deleteByIds(BaseMapper.java:219)
at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:166)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
at jdk.proxy2/jdk.proxy2.$Proxy176.deleteByIds(Unknown Source)
at com.baomidou.mybatisplus.core.mapper.BaseMapper.deleteByIds(BaseMapper.java:185)
at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:166)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
at jdk.proxy2/jdk.proxy2.$Proxy176.deleteByIds(Unknown Source)
at com.baomidou.mybatisplus.extension.service.IService.removeByIds(IService.java:159)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716)
at kare.freebird.system.service.impl.SysUserTokenServiceImpl$$SpringCGLIB$$0.removeByIds(<generated>)
at test.DemoTest.test3(DemoTest.java:23)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.util.UUID'
at org.apache.ibatis.reflection.Reflector.getGetInvoker(Reflector.java:385)
at org.apache.ibatis.reflection.MetaClass.getGetInvoker(MetaClass.java:160)
at org.apache.ibatis.reflection.wrapper.BeanWrapper.getBeanProperty(BeanWrapper.java:156)
at org.apache.ibatis.reflection.wrapper.BeanWrapper.get(BeanWrapper.java:50)
at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:115)
at org.apache.ibatis.reflection.wrapper.BaseWrapper.getChildValue(BaseWrapper.java:121)
at org.apache.ibatis.reflection.wrapper.MapWrapper.get(MapWrapper.java:42)
at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:115)
at org.apache.ibatis.mapping.BoundSql.getAdditionalParameter(BoundSql.java:74)
at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:73)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:97)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:65)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
at jdk.proxy2/jdk.proxy2.$Proxy199.parameterize(Unknown Source)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:91)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:61)
at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:106)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:59)
at jdk.proxy2/jdk.proxy2.$Proxy198.update(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197)
at org.apache.ibatis.session.defaults.DefaultSqlSession.delete(DefaultSqlSession.java:212)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:333)
... 24 more

@miemieYaho
Copy link
Member

mybatis没有UUID的对应typehandler

@zijun-hiwintech
Copy link
Author

zijun-hiwintech commented Jan 23, 2025

嗯 感觉您的回复,但是我们自己实现了一个UUIDTypeHandler 现在的代码在mybatis 3.5.6 可以正常执行 但是之后的版本就报上述的错误

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.StringUtils;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;

@MappedTypes(UUID.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class UUIDTypeHandler extends BaseTypeHandler {

@Override
public UUID getNullableResult(ResultSet rs, String strArg)
        throws SQLException {
    String strVal = rs.getString(strArg);
    return this.getUUIDFromString(strVal);
}

@Override
public UUID getNullableResult(ResultSet rs, int intArg) throws SQLException {
    String strVal = rs.getString(intArg);
    return this.getUUIDFromString(strVal);
}

@Override
public UUID getNullableResult(CallableStatement cs, int intArg)
        throws SQLException {
    String strVal = cs.getString(intArg);
    return this.getUUIDFromString(strVal);
}

@Override
public void setNonNullParameter(PreparedStatement ps, int intArg,
                                UUID uuid, JdbcType jdbcType) throws SQLException {
    if (null != uuid) {
        ps.setObject(intArg, uuid);
    }
}

private UUID getUUIDFromString(String uuidStr) {
    if (StringUtils.hasLength(uuidStr)) {
        return UUID.fromString(uuidStr);
    }
    return null;
}

}

@miemieYaho
Copy link
Member

后面的版本支持了在逻辑删除下能自动填充字段
你自己debug找问题吧,你找出来我们再考虑一下要不要修

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants