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
相关产品推荐
相关产品推荐

