为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:dm8
【操作系统】:centos7.6
【CPU】:
【问题描述】*:
使用mybatis plus 的insert语句报错,但复制SQL到dm工具里执行没问题
数据库大小写敏感
驱动版本:Dameng JDBC Driver V8.1.3.100-Build(2023.12.14-20748-)
报错信息如下:
org.springframework.dao.DataIntegrityViolationException:
### Error updating database. Cause: dm.jdbc.driver.DMException: 无效的列
### The error may exist in com/resettle/server/mapper/AccInfSpecMapper.java (best guess)
### The error may involve com.resettle.server.mapper.AccInfSpecMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO RESETTLEMENT."accInfSpec" ( "accInfSpecName", "accInfSpecUnit", "accSpecification", "notes" ) VALUES ( ?, ?, ?, ? )
### Cause: dm.jdbc.driver.DMException: 无效的列
; 无效的列; nested exception is dm.jdbc.driver.DMException: 无效的列
这是对象:
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "RESETTLEMENT.\"accInfSpec\"")
@ApiModel(value="AccInfSpec对象", description="附属物信息规范")
public class AccInfSpec implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "accInfSpecId", type = IdType.AUTO)
private int accInfSpecId;
private String accInfSpecName;
private String accInfSpecUnit;
private String accSpecification;
private String notes;
private Timestamp createtime;
}
这是查询:
@Override
public Boolean setAccInfSpec(AccInfSpec accInfSpec) {
try {
accInfSpecMapper.insert(accInfSpec);
return true;
} catch (Exception e) {
System.out.println(e);
throw new ServiceException(ErrorEnum.DATABASE_ERROR);
}
}
详细的数据库日志如下:
[DEBUG - 2024-01-30 22:20:14] tid:38 - [http-nio-9081-exec-4] { conn-1 } access(); CMD_PREPARE
[SQL - 2024-01-30 22:20:14] tid:38 - [http-nio-9081-exec-4] { conn-1 } prepareStatement(String, String[]): pstmt-5, handle-0; [PARAMS]: "INSERT INTO RESETTLEMENT."accInfSpec" ( "accInfSpecName",
"accInfSpecUnit",
"accSpecification",
"notes" ) VALUES ( ?,
?,
?,
? )", [Ljava.lang.String;@252ec386;
[INFO - 2024-01-30 22:20:14] tid:38 - [http-nio-9081-exec-4] { conn-1, pstmt-5 } setString(Integer, String); [PARAMS]: 1, "空调";
[INFO - 2024-01-30 22:20:14] tid:38 - [http-nio-9081-exec-4] { conn-1, pstmt-5 } setString(Integer, String); [PARAMS]: 2, "台";
[INFO - 2024-01-30 22:20:14] tid:38 - [http-nio-9081-exec-4] { conn-1, pstmt-5 } setString(Integer, String); [PARAMS]: 3, "挂式";
[INFO - 2024-01-30 22:20:14] tid:38 - [http-nio-9081-exec-4] { conn-1, pstmt-5 } setString(Integer, String); [PARAMS]: 4, "测试set接口";
[DEBUG - 2024-01-30 22:20:14] tid:38 - [http-nio-9081-exec-4] { conn-1 } access(); CMD_EXECUTE2
[ERROR - 2024-01-30 22:20:14] tid:38 - [http-nio-9081-exec-4] { conn-1, pstmt-5 } execute();
dm.jdbc.driver.DMException: 无效的列
at dm.jdbc.driver.DBError.throwException(DBError.java:711)
at dm.jdbc.a.b.o.x(MSG.java:591)
at dm.jdbc.a.b.o.C(MSG.java:526)
at dm.jdbc.a.b.o.B(MSG.java:507)
at dm.jdbc.a.a.a(DBAccess.java:245)
at dm.jdbc.a.a.a(DBAccess.java:944)
at dm.jdbc.a.a.a(DBAccess.java:813)
at dm.jdbc.driver.DmdbPreparedStatement.executeInner(DmdbPrepare
这是数据库表结构
CREATE TABLE "RESETTLEMENT"."accInfSpec"
(
"accInfSpecId" INT IDENTITY(1, 1) NOT NULL,
"accInfSpecName" VARCHAR(30) NOT NULL,
"accInfSpecUnit" VARCHAR(8) NOT NULL,
"accSpecification" VARCHAR(60) NOT NULL,
"notes" VARCHAR(200) DEFAULT '',
"createtime" TIMESTAMP(0) DEFAULT CURRENT_TIMESTAMP,
NOT CLUSTER PRIMARY KEY("accInfSpecId")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON TABLE "RESETTLEMENT"."accInfSpec" IS '附属物信息规范';
COMMENT ON COLUMN "RESETTLEMENT"."accInfSpec"."accInfSpecId" IS '附属物规范Id';
COMMENT ON COLUMN "RESETTLEMENT"."accInfSpec"."accInfSpecName" IS '附属物名称';
COMMENT ON COLUMN "RESETTLEMENT"."accInfSpec"."accInfSpecUnit" IS '附属物计量单位';
COMMENT ON COLUMN "RESETTLEMENT"."accInfSpec"."accSpecification" IS '附属物规格';
您好,您的提供的信息太完美了!点赞!
这个建议优先排查下服务端的版本
你给出来的这个驱动版本非常新,怀疑是驱动问题或者和老版本的兼容性问题
建议也给出来来连接串配置方法(模糊IP端口用户名密码即可)包括服务名里面,是否有配置prepareOptimize或者兼容性等参数
您可以尝试使用和服务端匹配的驱动进行确认
另外,建议提供下这个实体对象的mapper文件。
该问题,从您提供的信息来看,大概率是自增列影响的。可能是驱动和服务单的兼容性问题或者产品本身的问题。
非常抱歉给您造成此类困扰。
该问题的解决方案为:在url中添加 genKeyNameCase=0的参数
改参数的详细解释如下:
文档来源:DM JDBC 编程指南 | 达梦技术文档
排查思路如下:
1)通过您提供的非常清晰的jdbc日志可只,sql绝对没问题;但是在execute的时候报错无效的列名,那么是否是表上有其他特殊列
2) 查看表结构,发现确实有一个自增列,这个在程序和框架中,如果执行了插入,一般一定要反馈资格自增列的值,以供后续处理
3)那么正如前面所说,我们做的第一个事情和怀疑就是,是否把这个自增列改成大写后,程序运行就不报错了;通过您的demo确认后,确实如此
4)那么该问题,大概率是有参数控制的,通过查阅程序员手册jdbc章节,可以看到确实有上述参数;改回原来的表结构,在url中添加该参数的配置为0后,程序依然正常。
关于该问题,达梦的字段名、对象名;是通过不管应用程序怎么写,只要不带双引号,我们都会统一转换为大写进行处理;这样实现的好处就是,不管我们是大写、小写、驼峰等等,都能正确匹配,实现对象字段名字的大小写“无感”。但是在框架的实现中,为了考虑通用性考虑,都会为对象添加双引号,以匹配大小写。
因此,该问题的直接解决方式是,在url中添加&genKeyNameCase=0
优选方案是:class AccInfSpec 这个实体文件中的对象名、字段名全部大写;服务端表名、字段名,也都大写。
还是要惊呼,您提交的这个问题,太专业了;信息清晰、日志齐全、一眼洞穿!为您这个问题点赞!对这个问题给你造成的困扰,十分抱歉!
您好 按照下面的修改 新增是可以了 但是查询又报错了
一般是驱动和数据库版本不匹配。在数据库服务器dmdbms/drivers/jdbc目录下获取同版本的驱动试试