You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Exposed操作H2数据库插入成功但查询失败问题求助

问题原因
  • 核心原因:Exposed框架的Table类默认要求每个表必须定义主键,你当前的AuthorTable未声明任何主键,执行查询操作时,Exposed内部的结果集映射逻辑无法找到主键字段触发空指针异常,就是你看到的报错。
  • 附加隐患:你使用的H2内存数据库默认配置下,最后一个连接关闭后整个数据库实例会被销毁,第一个transaction执行完成后连接释放,就算解决了主键问题,第二个transaction查询时也会找不到之前插入的数据。
解决办法

1. 给AuthorTable添加主键定义,两种可选方案

方案一:新增自增ID作为主键

修改表结构定义代码:

package learn.exposed.tables

import org.jetbrains.exposed.sql.Table

object AuthorTable : Table("author") {
    val id = integer("id").autoIncrement()
    val name = varchar("name", 30)
    // 指定主键
    override val primaryKey = PrimaryKey(id, name = "PK_Author_Id")
}

同步修改create.sql的建表语句:

create table author (
    id int auto_increment primary key,
    name varchar(30)
);

同步修改init.sql的插入语句,适配新增的id列:

insert into author(name) values ('author1');

方案二:将现有name字段设为主键(仅适用于name字段全局唯一的场景)

修改表结构定义代码:

package learn.exposed.tables

import org.jetbrains.exposed.sql.Table

object AuthorTable : Table("author") {
    val name = varchar("name", 30)
    override val primaryKey = PrimaryKey(name)
}

同步修改create.sql的建表语句:

create table author (
    name varchar(30) primary key
);

2. 修改H2连接配置,避免内存数据库自动销毁

在原有JDBC URL中添加DB_CLOSE_DELAY=-1参数,修改后代码如下:

val url = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/create.sql'\\;runscript from 'classpath:/init.sql'"

该参数会让H2内存数据库一直保留到JVM进程退出,不会随连接关闭销毁。

内容的提问来源于stack exchange,提问作者sho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 02:06:04