开发者社区 > 云原生 > 正文

PgSQL 执行插入具有multi pk 特性的表, 出现空指针异常

问题描述

我使用的版本: seata-all:1.6.0 我的表为分区表: form, 其中主键为(form_id, bu_id) (bu_id为分区键, form_id为未分区前的业务主键) 分区表的form_id采用了数据库自增特性 现在对form表执行插入操作, 需要有全局事务控制, 添加了@GlobalTransaction注解 结果报空指针异常

发生情况

2023-01-09 14:23:40.069 [TID:19c8ba3313cc470386af1f0888f3d4f2.186.16732444819040003] [http-nio-11212-exec-2] ERROR com.wditech.tpm.service.dependency.exception.GlobalExceptionHandler - 兜底异常处理:

Error updating database. Cause: java.sql.SQLException: java.lang.NullPointerException

The error may exist in com/wditech/tpm/bus/common/infrastructure/repository/mapper/FormMapper.java (best guess)

The error may involve com.wditech.tpm.bus.common.infrastructure.repository.mapper.FormMapper.insert-Inline

The error occurred while setting parameters

SQL: INSERT INTO form ( bu_Id, form_no, process_id, status_id, user_id, position_id, dept_id, form_type_id, page_group_id, page_type_id, submit_date, amount, summary, in_turn_user_names, in_turn_position_ids, last_approved_date, warning_ids, export_status, submit_date_original ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

Cause: java.sql.SQLException: java.lang.NullPointerException

org.apache.ibatis.exceptions.PersistenceException:

Error updating database. Cause: java.sql.SQLException: java.lang.NullPointerException

The error may exist in com/wditech/tpm/bus/common/infrastructure/repository/mapper/FormMapper.java (best guess)

The error may involve com.wditech.tpm.bus.common.infrastructure.repository.mapper.FormMapper.insert-Inline

The error occurred while setting parameters

SQL: INSERT INTO form ( bu_Id, form_no, process_id, status_id, user_id, position_id, dept_id, form_type_id, page_group_id, page_type_id, submit_date, amount, summary, in_turn_user_names, in_turn_position_ids, last_approved_date, warning_ids, export_status, submit_date_original ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )

Cause: java.sql.SQLException: java.lang.NullPointerException

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.insert(DefaultSqlSession.java:184)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)
at com.sun.proxy.$Proxy169.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:271)
at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:60)
at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:96)
at com.sun.proxy.$Proxy178.insert(Unknown Source)
at com.baomidou.mybatisplus.extension.service.IService.save(IService.java:59)
at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
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:763)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
at com.wditech.tpm.bus.common.infrastructure.repository.FormRepositoryImpl$$EnhancerBySpringCGLIB$$120c9300.save(<generated>)
at com.wditech.tpm.bus.project.domain.service.impl.FormBudgetProjectServiceImpl.create(FormBudgetProjectServiceImpl.java:91)
at com.wditech.tpm.bus.project.domain.service.impl.FormBudgetProjectServiceImpl$$FastClassBySpringCGLIB$$6700d7d9.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at io.seata.spring.annotation.GlobalTransactionalInterceptor$2.execute(GlobalTransactionalInterceptor.java:204)
at io.seata.tm.api.TransactionalTemplate.execute(TransactionalTemplate.java:130)
at io.seata.spring.annotation.GlobalTransactionalInterceptor.handleGlobalTransaction(GlobalTransactionalInterceptor.java:201)
at io.seata.spring.annotation.GlobalTransactionalInterceptor.invoke(GlobalTransactionalInterceptor.java:171)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
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:763)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
at com.wditech.tpm.bus.project.domain.service.impl.FormBudgetProjectServiceImpl$$EnhancerBySpringCGLIB$$efe55ce9.create(<generated>)
at com.wditech.tpm.bus.project.application.service.impl.FormBudgetProjectApplicationServiceImpl.apply(FormBudgetProjectApplicationServiceImpl.java:194)
at com.wditech.tpm.bus.project.application.service.impl.GeneralFormBudgetProjectApplicationService.apply(GeneralFormBudgetProjectApplicationService.java:29)
at com.wditech.tpm.bus.project.controller.ButtonsController.apply$original$IGCXqL8Y(ButtonsController.java:83)
at com.wditech.tpm.bus.project.controller.ButtonsController.apply$original$IGCXqL8Y$accessor$t0bmjf72(ButtonsController.java)
at com.wditech.tpm.bus.project.controller.ButtonsController$auxiliary$QeWsl42M.call(Unknown Source)
at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86)
at com.wditech.tpm.bus.project.controller.ButtonsController.apply(ButtonsController.java)
at com.wditech.tpm.bus.project.controller.ButtonsController$$FastClassBySpringCGLIB$$c3903034.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:123)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
at com.wditech.tpm.bus.project.controller.ButtonsController$$EnhancerBySpringCGLIB$$24c69e88.apply(<generated>)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
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:1070)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
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:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.wditech.tpm.service.dependency.config.MyFilter.doFilter(MyFilter.java:48)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
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:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
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:541)
at org.apache.catalina.core.StandardHostValve.invoke$original$7CIw0ueW(StandardHostValve.java:135)
at org.apache.catalina.core.StandardHostValve.invoke$original$7CIw0ueW$accessor$lt3L4p5p(StandardHostValve.java)
at org.apache.catalina.core.StandardHostValve$auxiliary$yQzq70fk.call(Unknown Source)
at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789)
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.base/java.lang.Thread.run(Thread.java:834)

Caused by: java.sql.SQLException: java.lang.NullPointerException at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:141) at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:56) at io.seata.rm.datasource.PreparedStatementProxy.execute(PreparedStatementProxy.java:55) at jdk.internal.reflect.GeneratedMethodAccessor277.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59) at com.sun.proxy.$Proxy401.execute(Unknown Source) at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:47) at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:74) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) at com.sun.proxy.$Proxy400.update(Unknown Source) at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.doUpdate(MybatisSimpleExecutor.java:54) at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) at com.baomidou.mybatisplus.core.executor.MybatisCachingExecutor.update(MybatisCachingExecutor.java:83) at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197) ... 113 common frames omitted Caused by: java.lang.NullPointerException: null at io.seata.rm.datasource.exec.BaseTransactionalExecutor.buildTableRecords(BaseTransactionalExecutor.java:515) at io.seata.rm.datasource.exec.BaseInsertExecutor.afterImage(BaseInsertExecutor.java:79) at io.seata.rm.datasource.exec.AbstractDMLBaseExecutor.executeAutoCommitFalse(AbstractDMLBaseExecutor.java:98) at io.seata.rm.datasource.exec.AbstractDMLBaseExecutor.lambda$executeAutoCommitTrue$2(AbstractDMLBaseExecutor.java:137) at io.seata.rm.datasource.ConnectionProxy$LockRetryPolicy.doRetryOnLockConflict(ConnectionProxy.java:356) at io.seata.rm.datasource.exec.AbstractDMLBaseExecutor$LockRetryPolicy.execute(AbstractDMLBaseExecutor.java:180) at io.seata.rm.datasource.exec.AbstractDMLBaseExecutor.executeAutoCommitTrue(AbstractDMLBaseExecutor.java:136) at io.seata.rm.datasource.exec.AbstractDMLBaseExecutor.doExecute(AbstractDMLBaseExecutor.java:82) at io.seata.rm.datasource.exec.BaseTransactionalExecutor.execute(BaseTransactionalExecutor.java:125) at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:137) ... 132 common frames omitted

期待结果:期望执行插入成功

如何复制

1、数据表脚本

create table form ( form_id serial, bu_id smallint, form_no varchar(64) ) PARTITION BY LIST (bu_id);

CREATE TABLE form_bu1 PARTITION OF form FOR VALUES in(1); CREATE TABLE form_bu2 PARTITION OF form FOR VALUES in(2); CREATE TABLE form_bu3 PARTITION OF form FOR VALUES in(3);

alter table form add primary key (form_id, bu_id);

2、对表执行插入操作的方法添加@GlobalTransaction注解

3、报错

其他信息

1、110行获取的insertColumns变量中, 不包含form_id(是否是因为我使用form_id的自增, 所以这里获取不到自增的列), 只有bu_id, form_no

提问10.png

2、导致513行中pkValuesMap只有一个bu_id, 而pkColumnNameList则有form_id, bu_id两个, 最终导致空指针

提问11.png

环境信息

JDK version : % Java -version java version "11.0.16" 2022-07-19 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.16+11-LTS-199) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.16+11-LTS-199, mixed mode) Seata version: 1.6.0 OS : Mac OS 13.1 (22C65) Apple M1 Pro

原提问者GitHub用户lavenwl

展开
收起
学习娃 2023-06-14 16:57:15 59 0
1 条回答
写回答
取消 提交回答
  • 从代码中可以看出,似乎不支持自递增列主键,这是一个有待讨论的问题

    回答2.png

    原回答者GitHub用户a364176773

    2023-06-14 17:27:43
    赞同 展开评论 打赏

阿里云拥有国内全面的云原生产品技术以及大规模的云原生应用实践,通过全面容器化、核心技术互联网化、应用 Serverless 化三大范式,助力制造业企业高效上云,实现系统稳定、应用敏捷智能。拥抱云原生,让创新无处不在。

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载