故障排查
本章收集常见安装、查询和运行时排查步骤。
安装、SQL 生成或运行结果需要检查时,可以从本页按入口定位。
检查依赖坐标
Kronos 依赖使用文档宏中的稳定版本,第三方驱动使用匹配数据库和 JDK 的当前稳定版。
build.gradle.kts
dependencies {
implementation("com.kotlinorm:kronos-core:0.4.0")
implementation("com.kotlinorm:kronos-jdbc-wrapper:0.4.0")
implementation("com.mysql:mysql-connector-j:<latest-stable>")
}将 <latest-stable> 替换为当前数据库和 JDK 可用的稳定驱动版本。
检查编译插件配置
Kronos 编译期支持在 Kotlin 编译时加载。编译声明 KPojo 或编写 Kronos DSL 的模块,并查看构建输出。
Gradle
./gradlew :app:compileKotlinoutput
[Kronos] Kronos compiler plugin K2 initialized
BUILD SUCCESSFUL声明实体或查询 DSL 的每个 source set 都需要启用 Kronos Gradle 或 Maven 插件。完整构建示例和 source set 规则见 📚编译器插件。
检查 KPojo generated members
__tableName、toDataMap()、__columns 和动态访问器会在 source set 经过 Kronos 编译后可用。
kotlin
val user = User(id = 7, name = "Ada")
println(user.__tableName)
println(user.toDataMap())
println(user.__columns.map { it.name })output
tb_user
{id=7, name=Ada}
[id, name]运行结果出现 __tableName must be overridden by the compiler plugin 时,为该模块启用 Kronos 编译插件并重新导入 IDE 项目。完整检查见 📚检查生成的 KPojo 成员。
projection alias 或标量子查询诊断
投影结果字段需要稳定名称。函数、聚合、窗口函数、原生 SQL 和标量子查询作为 select item 时,给它们设置 alias。
alias
User()
.select { [it.id, f.length(it.name).alias("nameLength")] }
.toList()标量子查询作为值使用时,选择一个字段并使用 limit(1)。
scalar
User()
.select { user ->
[
user.id,
Order()
.select { it.amount }
.where { it.userId == user.id }
.limit(1)
.alias("lastAmount")
]
}
.toList()KRONOS_SELECT_ITEM_REQUIRES_ALIAS、KRONOS_SCALAR_SUBQUERY_REQUIRES_LIMIT 和 KRONOS_SCALAR_SUBQUERY_REQUIRES_SINGLE_COLUMN 这些诊断码见 📚修复常见诊断。查询形态示例见 📚投影 和 📚子查询。
配置数据源
Kronos ORM 操作需要配置 Kronos.dataSource。
kotlin
val wrapper = KronosJdbcWrapper(dataSource)
Kronos.dataSource = { wrapper }
val users = User().select().toList()某次操作需要指定数据源时,可以直接通过 wrapper 执行。
wrapper
val users = User()
.select()
.toList(wrapper)方言输出与预期不同
Kronos 根据 KronosDataSourceWrapper.dbType 渲染 SQL。标识符引用或分页语法不符合预期时,打印 wrapper 当前值。
kotlin
val wrapper = KronosJdbcWrapper(dataSource)
println(wrapper.dbType)
println(wrapper.sqlDialect)标识符引用、分页、upsert、DDL 和函数示例见 📚数据库方言支持。
检查 where() 条件
select() 只选择表和投影。空 where() 会按当前对象的可查询非空字段生成 query-by-example 条件。
select
User(id = 1).select()
// SELECT ... FROM user
User(id = 1).select().where()
// WHERE id = 1带 lambda 的 where 由 lambda 控制本次条件。
lambda
User(id = 1)
.select()
.where { it.name == "Ada" }
// WHERE name = 'Ada'where 组合规则见 📚条件表达式。
检查 DataGuard 写入和 DDL 保护
DataGuard 会在执行前拦截全表写入和受保护的表操作。
result
DataGuardPlugin.enable()
User()
.delete()
.execute()error
UnsupportedOperationException: Delete operation is not allowed.为计划内维护操作增加条件,或配置允许规则。
allow
DataGuardPlugin.enable {
deleteAll {
allow {
tableName = "tmp_import_error"
}
}
}策略示例见 📚DataGuard。
逻辑删除或乐观锁改变了 SQL
逻辑删除和乐观锁注解会根据 KPojo 元数据增加写入条件或赋值。
kotlin
data class User(
@PrimaryKey
var id: Int? = null,
@LogicDelete
@Default("0") // @Default("false") for Postgres
var deleted: Boolean? = null,
@Version
var version: Int? = null
) : KPojo查看生成 SQL
页面说明了 build...Task 形式时,可以先构建任务再查看 SQL。
kotlin
val task = Kronos.dataSource.table.buildCreateTableAsSelectTask(
OrderArchive(),
Order().select { [it.id, it.userId] }
)
println(task.sql)
println(task.paramMap)select、join、subquery 和 CTAS 的 SQL 示例见 📚子查询 和 📚基于查询创建表。
Codegen 或 IDE 插件入口
数据库元数据需要生成 KPojo 文件时,使用 Codegen。
codegen
@file:DependsOn("com.kotlinorm:kronos-codegen:0.4.0")编辑器支持和诊断入口见 KEFS 配置页面。
pages
资源 -> 代码生成器
资源 -> KEFS 编辑器支持详见 📚代码生成器 和 📚KEFS 编辑器支持。