为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:8
【操作系统】:centos
【CPU】: 8
【问题描述】*:sprungboot3.2 + mybatis-plus3.5.2 + DM8数据库集成shardingsphere-jdbc-core5.1.2 分库分表操作,通过tenant_id实现多租户管理,在通过tenant_id查询、删除、修改的时候正常无误,但是通过Iservice、BaseMapper的save(),insert()等新增方法时候出现
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: Error preparing statement. Cause: java.lang.NullPointerException
......
Caused by: org.apache.ibatis.executor.ExecutorException: Error preparing statement. Cause: java.lang.NullPointerException
......
Caused by: java.lang.NullPointerException
at org.apache.shardingsphere.infra.binder.segment.insert.keygen.engine.GeneratedKeyContextEngine.findGenerateKeyColumn(GeneratedKeyContextEngine.java:63)
at org.apache.shardingsphere.infra.binder.segment.insert.keygen.engine.GeneratedKeyContextEngine.createGenerateKeyContext(GeneratedKeyContextEngine.java:57) at org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext.<init>(InsertStatementContext.java:96)
at org.apache.shardingsphere.infra.binder.SQLStatementContextFactory.getDMLStatementContext(SQLStatementContextFactory.java:167)
at org.apache.shardingsphere.infra.binder.SQLStatementContextFactory.newInstance(SQLStatementContextFactory.java:141)
at org.apache.shardingsphere.infra.binder.SQLStatementContextFactory.newInstance(SQLStatementContextFactory.java:126)
at org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement.<init>(ShardingSpherePreparedStatement.java:180)
at org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSpherePreparedStatement.<init>(ShardingSpherePreparedStatement.java:148)
at org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection.prepareStatement(ShardingSphereConnection.java:86)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:86)
at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88)
... 105 more
以上的报错信息,分库分表部分配置如下
# 逻辑库
logic-database-name: HORAE
# 公共库数据源
source-database-name: HORAE_1001
# 数据库分片键
database-sharding-column: TENANT_ID
# 分库规则行表达式
database-sharding-algorithm-expression: "HORAE_${TENANT_ID}"
# 获取租户数据源sql
datasource-sql: "SELECT T1.TENANT_ID AS TENANT_ID, T1.DATASOURCE_URL AS DATASOURCE_URL,T1.DATASOURCE_USERNAME AS DATASOURCE_USERNAME, T1.DATASOURCE_PASSWORD AS DATASOURCE_PASSWORD,
T1.DATASOURCE_DRIVER AS DATASOURCE_DRIVER, T2.USE_STATE AS STATUS
FROM HORAE.SYS_TENANT_DATASOURCE T1
LEFT JOIN HORAE.SYS_TENANT_INFO T2 ON T1.TENANT_ID = T2.TENANT_ID AND T2.USE_STATE = 1"
# 分片规则查询sql
table-sharding-rule-sql: SELECT TABLE_NAME,SHARDING_COLUMNS,HAS_SHARDING_COLUMN,BIND_TABLE,PUBLIC_TABLE_FLAG,SHARDING_ALGORITHM_NAME,STATUS FROM HORAE.SYS_TABLE_SHARDING_RULE
参考源码,根据报错是以下函数返回了空指针return xxx.empty()
,请检查是否存在对应的表(注意大小写和模式是否对应)、表是否没有设置自增列(这是数据库层面的,ShardingSphere不管)
private Optional<String> findGenerateKeyColumn(final String tableName) {
if (!schema.containsTable(tableName)) {
return Optional.empty();
}
for (Entry<String, ShardingSphereColumn> entry : schema.get(tableName).getColumns().entrySet()) {
if (entry.getValue().isGenerated()) {
return Optional.of(entry.getKey());
}
}
return Optional.empty();
}
根据报错提示,应该还没到达梦驱动层,根据报错可能在预编译准备sql部分就报错了,建议一步步调试定位原因