java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MybatisPlus批量插入数据报错

解决MybatisPlus批量插入数据报错:Error getting generated key or setting result to parameter object问题

作者:Duktig丶

在使用MybatisPlus进行批量插入数据时遇到空指针异常错误,分析原因是由于主键生成策略导致的,尝试通过设置useGeneratedKeys属性解决问题,但因批量插入方法限制,该方法未能成功,最终通过自定义mapper方法实现批量插入,解决了问题

问题描述

执行的核心代码:

objectUserService.saveBatch(objectUserList);

在使用MybatisPlus进行执行批量插入操作的时候报错,导致每次插入数据失败。

具体报错信息如下:

xiaoyun_notice- 2020-07-14 20:34:09 [http-nio-9001-exec-1] INFO  c.x.api.controller.ObjectController - 【新增通知:step02-object_user批量新增,维护中间表】: userId: 2
xiaoyun_notice- 2020-07-14 20:34:09 [http-nio-9001-exec-1] INFO  jdbc.sqltiming - batching 3 statements: 1: INSERT INTO object_user ( obj_id, user_id ) VALUES ( 151, 1 ) 2: 
INSERT INTO object_user ( obj_id, user_id ) VALUES ( 151, 2 ) 3: INSERT INTO object_user ( 
obj_id, user_id ) VALUES ( 151, 3 ) ;
 {executed in 75 msec}
xiaoyun_notice- 2020-07-14 20:34:09 [http-nio-9001-exec-1] INFO  jdbc.sqltiming - getGeneratedKeys on query: INSERT INTO object_user ( obj_id, user_id ) VALUES ( 151, 3 ) ;
 {executed in 0 msec}
xiaoyun_notice- 2020-07-14 20:34:09 [http-nio-9001-exec-1] ERROR c.x.e.handler.GlobalExceptionHandler - nested exception is org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: java.lang.NullPointerException
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: java.lang.NullPointerException

主要报错信息:

ERROR c.x.e.handler.GlobalExceptionHandler - nested exception is org.apache.ibatis.executor.ExecutorException: Error getting generated key or setting result to parameter object. Cause: java.lang.NullPointerException

问题分析

根据上述的主要报错信息,可以推测出MybatisPlus在底层执行新增操作时,返回的主键为空,报了个空指针的异常,又因为加了事务的缘故,所以每次执行新增操作,失败。

问题解决过程

百度上所说的大多数的解决策略都是说主键生成策略的问题。

即设置mybatis的insert语句useGeneratedKeys属性为false即可解决问题。

网上大多使用的xml去配置,可以在写到SpringBoot的时候,基本就不怎么写xml文件,多以就想着使用注解去设置,还真有设置这样的注解。

@Options(useGeneratedKeys=true,keyProperty="id",keyColumn="id")

option注解标签useGeneratedKeys=true表示使用数据库自动增长的主键,keyColumn用于指定数据库table中的主键,keyProperty用于指定传入对象的成员变量。

Springboot中 Mybatis 配置文件 Mapper参数useGeneratedKeys=“true” keyProperty=“id”,useGeneratedKeys设置为 true 时,表示如果插入的表id以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键id返回。

useGeneratedKeys参数只针对 insert 语句生效,默认为 false;

默认为false怎么还会生效?难道说是MybatisPlus底层有做了处理。

局限性

虽然这样使用可能可以成功,但是批量插入的方法,是MybatisPlus底层提供的,我们没有办法在mapper中添加这个注解,将这个注解添加到当前方法,还是失败。

后续更新

经过各种尝试,这样的方法还是失败,所以这个需求暂时不使用MybatisPlus的批量新增来写了,就自己写个新增的mapper方法吧。

替代解决方案

因为项目开发需要,不能再耗时间,所以干脆就在写个自定义的mapper批量新增的方法来解决这个问题吧。

方法如下:

/**
 * description: 新增通知时,维护中间表,批量新增
 *
 * @param objId   通知id
 * @param userIds 用户id集合
 * @return 执行条数
 */
@Insert({
        "<script>",
        "INSERT INTO object_user(obj_id, user_id,created_at,updated_at) values ",
        "<foreach collection='userIds' item='item' index='index' separator=','>",
        "(#{objId}, #{item},now(),now())",
        "</foreach>",
        "</script>"
})
int saveObjectUserList ( int objId, List<Integer> userIds );

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文