zl程序教程

您现在的位置是:首页 >  其他

当前栏目

【异常】MyBatis-Plus因@TableId错误使用,导致主键未生成,SQL异常提示SQLException: Field ‘xxx‘ doesn‘t have a default value

错误mybatisSQL异常 生成 提示 value 导致
2023-09-14 09:04:55 时间

一、异常内容

org.springframework.dao.DataIntegrityViolationException: 
### Error updating database.  Cause: java.sql.SQLException: Field 'crash_id' doesn't have a default value
### The error may exist in com/desaysv/apb/terminal/mapper/CrashLogMapper.java (best guess)
### The error may involve com.desaysv.apb.terminal.mapper.CrashLogMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO t_crash_log_main  ( log_type, project_name, create_time, upload_time, soft_ware_version, log_hash, device_id, fingerprint, package_name, repeat_flag,  project_id, exception_url )  VALUES  ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,  ?, ? )
### Cause: java.sql.SQLException: Field 'crash_id' doesn't have a default value
; Field 'crash_id' doesn't have a default value; nested exception is java.sql.SQLException: Field 'crash_id' doesn't have a default value
	at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:251)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70)
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:91)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
	at com.sun.proxy.$Proxy145.insert(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:272)
 

二、异常说明

实现类如下

@Slf4j
@Service
@AllArgsConstructor
public class LogServiceImpl implements LogService {

    private final CrashLogMapper crashLogMapper;

    @Override
    public JSON  saveData(String data) {
		CrashLog crashLog = getCrashLog(data);
		crashLogMapper.insert(crashLog);
		//略
		return new JSONObject;
	}
}

获取实体内容如下,注意,没有加CrashID的赋值

public CrashLog getCrashLog(String data) {
		//转换data成实体略	
        CrashLog crashLog = new CrashLog();
        //参数赋值略
}

实体定义如下,其中使用了@TableId(type = IdType.AUTO)注解

@Setter
@Getter
@TableName(value = "t_crash_log_main", autoResultMap = true)
public class CrashLog implements Serializable {

    private static final long serialVersionUID = -8276789185001719920L;
    /**
     * 主键
     */
    @TableId(type = IdType.AUTO)
    private String crashId;
}

三、报错解决

3.1 修改点1:支持MP的实体

将原来的implements Serializable { 改成extends Model<CrashLog> {

@Setter
@Getter
@TableName(value = "t_crash_log_main", autoResultMap = true)
public class CrashLog extends Model<CrashLog> {

    private static final long serialVersionUID = -8276789185001719920L;
    /**
     * 主键
     */
    @TableId(type = IdType.AUTO)
    private String crashId;

3.2 修改点2:系统生成主键

加了@TableId(type = IdType.AUTO) 注解,但未自动生成主键 (@TableId和字段类型问题)

public CrashLog getCrashLog(String data) {
		//转换data成实体略	
        CrashLog crashLog = new CrashLog();
        crashLog.setCrashId(IdUtil.fastSimpleUUID()) ;
        //其他参数的赋值略
}

四、 Mybatis Plus的主键策略

有如下几种:

public enum IdType {
    AUTO(0),
    NONE(1),
    INPUT(2),
    ASSIGN_ID(3),
    ASSIGN_UUID(4);
    private final int key;
    private IdType(int key) {
        this.key = key;
    }
    public int getKey() {
        return this.key;
    }
}

4.1 AUTO

  • 数据库ID自增
  • 使用AUTO策略时,数据库建表时需要将主键设置成AUTO_INCREMENT,否则会插入不了
  • 使用AUTO,INPUT,ID_WORKER时,数据库字段需要是int,不建议将数据库id字段设计为string类型
  • 使用AUTO,INPUT,ID_WORKER时,entity代码中id的类型要为Long,不能是基础类型long

本文就是string类型 的 AUTO ,因此无法实现数据库ID的自动生成。

4.2 NONE

  • 该类型为未设置主键类型

4.3 INPUT

  • 用户输入ID
  • 使用AUTO,INPUT,ID_WORKER时,数据库字段需要是int、bigint也Ok
  • 使用AUTO,INPUT,ID_WORKER时,entity代码中id的类型要为Long,不能是基础类型long

4.4 其他

  • ID_WORKER 全局唯一ID,Long类型的主键
    全局唯一ID,Long类型的主键
    使用AUTO,INPUT,ID_WORKER时,数据库字段需要是int
  • ID_WORKER_STR 字符串全局唯一ID
    字符串全局唯一ID
    ID_WORKER_STR似乎无法自动生成主键了
  • 其中id_worker和id_worker_str当前版本似乎弃用
  • UUID 全局唯一ID,UUID类型的主键
    UUID类型的主键

五、参考文章

【异常】Mybatis-Plus的Integer类型的字段id设置成 @TableId(type = IdType.AUTO),但是因数据库有脏数据导致无法自动生成ID,提示空指针