apache / apache/incubator-seata

jdbcTemplate.batchUpdate 批量插入问题

Open
#3,190 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
26k
Forks
8.8k
Avg merge
1d 8h
Merged PRs (30d)
4

Description

- [ ] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate.

### Ⅰ. Issue Description
jdbcTemplate.batchUpdate(sql,args);没有问题可以正常执行
jdbcTemplate.batchUpdate(sqls);会报空指针异常

### Ⅱ. Describe what happened
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1013) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:665) ~[javax.servlet-api-4.0.1.jar:4.0.1]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:750) ~[javax.servlet-api-4.0.1.jar:4.0.1]
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90) ~[spring-boot-actuator-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:117) ~[spring-boot-actuator-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:106) ~[spring-boot-actuator-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.server.handlers.GracefulShutdownHandler.handleRequest(GracefulShutdownHandler.java:69) ~[undertow-core-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) [undertow-servlet-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360) [undertow-core-2.0.16.Final.jar:2.0.16.Final]
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) [undertow-core-2.0.16.Final.jar:2.0.16.Final]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_101]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_101]
at java.lang.Thread.run(Unknown Source) [na:1.8.0_101]
Caused by: java.lang.NullPointerException: null
at com.alibaba.druid.sql.parser.Lexer.charAt(Lexer.java:122) ~[druid-1.1.9.jar:1.1.9]
at com.alibaba.druid.sql.parser.Lexer.(Lexer.java:224) ~[druid-1.1.9.jar:1.1.9]
at com.alibaba.druid.sql.dialect.mysql.parser.MySqlLexer.(MySqlLexer.java:82) ~[druid-1.1.9.jar:1.1.9]
at com.alibaba.druid.sql.dialect.mysql.parser.MySqlExprParser.(MySqlExprParser.java:79) ~[druid-1.1.9.jar:1.1.9]
at com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser.(MySqlStatementParser.java:82) ~[druid-1.1.9.jar:1.1.9]
at com.alibaba.druid.sql.parser.SQLParserUtils.createSQLStatementParser(SQLParserUtils.java:77) ~[druid-1.1.9.jar:1.1.9]
at com.alibaba.druid.sql.parser.SQLParserUtils.createSQLStatementParser(SQLParserUtils.java:57) ~[druid-1.1.9.jar:1.1.9]
at com.alibaba.druid.sql.SQLUtils.parseStatements(SQLUtils.java:463) ~[druid-1.1.9.jar:1.1.9]
at io.seata.rm.datasource.sql.SQLVisitorFactory.get(SQLVisitorFactory.java:50) ~[seata-all-0.9.0.jar:0.9.0]
at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:73) ~[seata-all-0.9.0.jar:0.9.0]
at io.seata.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:47) ~[seata-all-0.9.0.jar:0.9.0]
at io.seata.rm.datasource.StatementProxy.executeBatch(StatementProxy.java:164) ~[seata-all-0.9.0.jar:0.9.0]
at org.springframework.jdbc.core.JdbcTemplate$1BatchUpdateStatementCallback.doInStatement(JdbcTemplate.java:550) ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate$1BatchUpdateStatementCallback.doInStatement(JdbcTemplate.java:536) ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:376) ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByCGLIB$$513fa28e.CGLIB$execute$8() ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByCGLIB$$513fa28e$$FastClassByCGLIB$$67d1079b.invoke() ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at cn.learningpad.common.log.sql.LoggableJdbcProxy$LoggableMedhodInterceptor.intercept(LoggableJdbcProxy.java:131) ~[classes/:na]
at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByCGLIB$$513fa28e.execute() ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:590) ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByCGLIB$$513fa28e.CGLIB$batchUpdate$65() ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByCGLIB$$513fa28e$$FastClassByCGLIB$$67d1079b.invoke() ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at cn.learningpad.common.log.sql.LoggableJdbcProxy$LoggableMedhodInterceptor.intercept(LoggableJdbcProxy.java:131) ~[classes/:na]
at org.springframework.jdbc.core.JdbcTemplate$$EnhancerByCGLIB$$513fa28e.batchUpdate() ~[spring-jdbc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at cn.learningpad.eda.school.dao.impl.GroupStudentDaoImpl.batchAddGroupStudent(GroupStudentDaoImpl.java:40) ~[classes/:na]
at cn.learningpad.eda.school.dao.impl.GroupStudentDaoImpl$$FastClassBySpringCGLIB$$dd2de216.invoke() ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at cn.learningpad.eda.school.dao.impl.GroupStudentDaoImpl$$EnhancerBySpringCGLIB$$cbcc6074.batchAddGroupStudent() ~[classes/:na]
at cn.learningpad.eda.school.service.impl.GroupServiceImpl.addGroup(GroupServiceImpl.java:79) ~[classes/:na]
at cn.learningpad.eda.school.service.impl.GroupServiceImpl$$FastClassBySpringCGLIB$$e84cdeb9.invoke() ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at cn.learningpad.eda.school.service.impl.GroupServiceImpl$$EnhancerBySpringCGLIB$$a339c8d5.addGroup() ~[classes/:na]
at cn.learningpad.eda.school.web.GroupController.createGroupInfo(GroupController.java:69) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_101]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at cn.learningpad.common.log.web.ControllerRecordLog.doInvoke(ControllerRecordLog.java:68) ~[classes/:na]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
... 60 common frames omitted

### Ⅲ. Describe what you expected to happen

### Ⅳ. How to reproduce it (as minimally and precisely as possible)

1. xxx
2. xxx
3. xxx

### Ⅴ. Anything else we need to know?
跟踪了一下,jdbcTemplate.batchUpdate(sqls);会执行
public StatementProxy(AbstractConnectionProxy connectionWrapper, T targetStatement) throws SQLException {
this(connectionWrapper, targetStatement, null);
}
导致解析sql异常

### Ⅵ. Environment:

- JDK version :100:
- OS :win7
- Others: seata 0.9.0

Contributor guide

Open the contributing guide

Research direction

Start at StatementProxy.executeBatch and ExecuteTemplate.execute in the stack trace, then follow the call into SQLVisitorFactory.get and the Druid SQL parser. Reproduce both JdbcTemplate.batchUpdate(sql,args) and batchUpdate(sqls) cases, identify why the latter reaches a null SQL value, and confirm that batch insertion completes without the NullPointerException.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
backend, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.