在使用SpringBoot时遇到的异常总结(持续更新...)

文章目录

  • 异常
    • MyBatis
      • java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
      • Mybatis-Plus查询语句无故自动加条件
      • Mybatis No enum constant org.apache.ibatis.type.JdbcType.TEXT
  • 参考文献

因为平时在写SpringBoot项目时,总是会遇到各种各样的异常,因此在这里记录一下,以便以后再遇到相同的错误时能够有一个参考

异常

MyBatis

java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails

时间:2023年09月18日

这个错误实际上并不是coding的问题,而是在向数据库中添加数据时出现的问题,更准确地说是外键约束的问题

  • squad表
    在使用SpringBoot时遇到的异常总结(持续更新...)_第1张图片
    在使用SpringBoot时遇到的异常总结(持续更新...)_第2张图片

  • member表
    在使用SpringBoot时遇到的异常总结(持续更新...)_第3张图片

可以看到member表中的字段group_id是一个外键(不考虑user_id这一字段)
但是我在向数据库member表中插入数据时,插入的内容是:
在这里插入图片描述
可以发现,向member表插入的数据中groupId=0,但是在squad表中并不存在id=0,所以出现上述异常
还有一个地方:为什么表的名字是squad而不是group/groups,因为group/groups都是mysql的关键字,具体请参考这篇文章:记录使用mybatis-plus时遇到的错误

Mybatis-Plus查询语句无故自动加条件

2023年09月18日

正常的查询语句:
在使用SpringBoot时遇到的异常总结(持续更新...)_第4张图片
在这里,查询语句是:

 SELECT COUNT(*) AS total FROM stakeholder WHERE deleted = 0 AND (user id = ?)

但是,这次遇到的问题是出现了错误的查询语句,导致没有办法进行正常的查询:
在使用SpringBoot时遇到的异常总结(持续更新...)_第5张图片
出现了错误的查询语句:

SELECT COUNT(*) AS total FROM stakeholder WHERE user_id = 0 AND (user_id = ?)

之所以会出现这样的问题,有两个方面的原因(因为我自己遇到了这两个方面的错误):

  1. 因为在DAO实体类中某一个成员属性是这样定义的:private int userId;,问题就在这里,int 类型的默认值为0,此处应该采用 Integer ,封装类,Integer的默认值为 null ,改为Integer后QueryMapper要搜索的其值就不是0了而是null,即对当前数据库中的表进行全查,而不是查0
  2. 因为我用到了逻辑删除,我自己将逻辑删除的注解@TableLogic放到了private Integer userId,导致出现了这样的问题

Mybatis No enum constant org.apache.ibatis.type.JdbcType.TEXT

2023年9月22日

在这里插入图片描述

当时我在mybatis的xml配置文件中,将jdbcType设置为和数据库保持一致的text类型,结果抛出了上述异常,JDBCType这个枚举类中不存在Text这个类型,那么我们需要查看一下JDBCType的源码:

public enum JDBCType implements SQLType {

    /**
     * Identifies the generic SQL type {@code BIT}.
     */
    BIT(Types.BIT),
    /**
     * Identifies the generic SQL type {@code TINYINT}.
     */
    TINYINT(Types.TINYINT),
    /**
     * Identifies the generic SQL type {@code SMALLINT}.
     */
    SMALLINT(Types.SMALLINT),
    /**
     * Identifies the generic SQL type {@code INTEGER}.
     */
    INTEGER(Types.INTEGER),
    /**
     * Identifies the generic SQL type {@code BIGINT}.
     */
    BIGINT(Types.BIGINT),
    /**
     * Identifies the generic SQL type {@code FLOAT}.
     */
    FLOAT(Types.FLOAT),
    /**
     * Identifies the generic SQL type {@code REAL}.
     */
    REAL(Types.REAL),
    /**
     * Identifies the generic SQL type {@code DOUBLE}.
     */
    DOUBLE(Types.DOUBLE),
    /**
     * Identifies the generic SQL type {@code NUMERIC}.
     */
    NUMERIC(Types.NUMERIC),
    /**
     * Identifies the generic SQL type {@code DECIMAL}.
     */
    DECIMAL(Types.DECIMAL),
    /**
     * Identifies the generic SQL type {@code CHAR}.
     */
    CHAR(Types.CHAR),
    /**
     * Identifies the generic SQL type {@code VARCHAR}.
     */
    VARCHAR(Types.VARCHAR),
    /**
     * Identifies the generic SQL type {@code LONGVARCHAR}.
     */
    LONGVARCHAR(Types.LONGVARCHAR),
    /**
     * Identifies the generic SQL type {@code DATE}.
     */
    DATE(Types.DATE),
    /**
     * Identifies the generic SQL type {@code TIME}.
     */
    TIME(Types.TIME),
    /**
     * Identifies the generic SQL type {@code TIMESTAMP}.
     */
    TIMESTAMP(Types.TIMESTAMP),
    /**
     * Identifies the generic SQL type {@code BINARY}.
     */
    BINARY(Types.BINARY),
    /**
     * Identifies the generic SQL type {@code VARBINARY}.
     */
    VARBINARY(Types.VARBINARY),
    /**
     * Identifies the generic SQL type {@code LONGVARBINARY}.
     */
    LONGVARBINARY(Types.LONGVARBINARY),
    /**
     * Identifies the generic SQL value {@code NULL}.
     */
    NULL(Types.NULL),
    /**
     * Indicates that the SQL type
     * is database-specific and gets mapped to a Java object that can be
     * accessed via the methods getObject and setObject.
     */
    OTHER(Types.OTHER),
    /**
     * Indicates that the SQL type
     * is database-specific and gets mapped to a Java object that can be
     * accessed via the methods getObject and setObject.
     */
    JAVA_OBJECT(Types.JAVA_OBJECT),
    /**
     * Identifies the generic SQL type {@code DISTINCT}.
     */
    DISTINCT(Types.DISTINCT),
    /**
     * Identifies the generic SQL type {@code STRUCT}.
     */
    STRUCT(Types.STRUCT),
    /**
     * Identifies the generic SQL type {@code ARRAY}.
     */
    ARRAY(Types.ARRAY),
    /**
     * Identifies the generic SQL type {@code BLOB}.
     */
    BLOB(Types.BLOB),
    /**
     * Identifies the generic SQL type {@code CLOB}.
     */
    CLOB(Types.CLOB),
    /**
     * Identifies the generic SQL type {@code REF}.
     */
    REF(Types.REF),
    /**
     * Identifies the generic SQL type {@code DATALINK}.
     */
    DATALINK(Types.DATALINK),
    /**
     * Identifies the generic SQL type {@code BOOLEAN}.
     */
    BOOLEAN(Types.BOOLEAN),

    /* JDBC 4.0 Types */

    /**
     * Identifies the SQL type {@code ROWID}.
     */
    ROWID(Types.ROWID),
    /**
     * Identifies the generic SQL type {@code NCHAR}.
     */
    NCHAR(Types.NCHAR),
    /**
     * Identifies the generic SQL type {@code NVARCHAR}.
     */
    NVARCHAR(Types.NVARCHAR),
    /**
     * Identifies the generic SQL type {@code LONGNVARCHAR}.
     */
    LONGNVARCHAR(Types.LONGNVARCHAR),
    /**
     * Identifies the generic SQL type {@code NCLOB}.
     */
    NCLOB(Types.NCLOB),
    /**
     * Identifies the generic SQL type {@code SQLXML}.
     */
    SQLXML(Types.SQLXML),

    /* JDBC 4.2 Types */

    /**
     * Identifies the generic SQL type {@code REF_CURSOR}.
     */
    REF_CURSOR(Types.REF_CURSOR),

    /**
     * Identifies the generic SQL type {@code TIME_WITH_TIMEZONE}.
     */
    TIME_WITH_TIMEZONE(Types.TIME_WITH_TIMEZONE),

    /**
     * Identifies the generic SQL type {@code TIMESTAMP_WITH_TIMEZONE}.
     */
    TIMESTAMP_WITH_TIMEZONE(Types.TIMESTAMP_WITH_TIMEZONE);

    /**
     * The Integer value for the JDBCType.  It maps to a value in
     * {@code Types.java}
     */
    private Integer type;

    /**
     * Constructor to specify the data type value from {@code Types) for
     * this data type.
     * @param type The value from {@code Types) for this data type
     */
    JDBCType(final Integer type) {
        this.type = type;
    }

    /**
     *{@inheritDoc }
     * @return The name of this {@code SQLType}.
     */
    public String getName() {
        return name();
    }
    /**
     * Returns the name of the vendor that supports this data type.
     * @return  The name of the vendor for this data type which is
     * {@literal java.sql} for JDBCType.
     */
    public String getVendor() {
        return "java.sql";
    }

    /**
     * Returns the vendor specific type number for the data type.
     * @return  An Integer representing the data type. For {@code JDBCType},
     * the value will be the same value as in {@code Types} for the data type.
     */
    public Integer getVendorTypeNumber() {
        return type;
    }
    /**
     * Returns the {@code JDBCType} that corresponds to the specified
     * {@code Types} value
     * @param type {@code Types} value
     * @return The {@code JDBCType} constant
     * @throws IllegalArgumentException if this enum type has no constant with
     * the specified {@code Types} value
     * @see Types
     */
    public static JDBCType valueOf(int type) {
        for( JDBCType sqlType : JDBCType.class.getEnumConstants()) {
            if(type == sqlType.type)
                return sqlType;
        }
        throw new IllegalArgumentException("Type:" + type + " is not a valid "
                + "Types.java value.");
    }
}

因此我们需要在\中将jdbcType设置为VARCHAR与数据库中Text类型数据进行映射

参考文献

1、MyBatis添加数据报错Cannot add or update a child row: a foreign key constraint fails
2、Mybatis-Plus查询语句无故自动加条件

你可能感兴趣的:(Java,spring,boot,后端,java)