HSQLDB执行JDBC代码报错user lacks privilege or object not found: PERSON
HSQLDB访问异常解决方案
异常根因分析
1. 空指针异常
SQL查询抛出异常时,ResultSet对象rs尚未完成初始化,finally代码块直接调用rs.close()触发空指针。
2. PERSON表不存在异常
该错误为核心报错,常见触发原因如下:
- 相对路径匹配错误:JDBC URL中使用的
./database/firstSQLAccess/为相对路径,匹配的是Java进程运行时的工作目录,而非项目源码目录。路径不匹配时HSQLDB会自动在目标路径新建空白数据库,自然找不到已创建的PERSON表,该问题占此类报错的90%以上。 - Schema不匹配:PERSON表未存储在当前连接默认使用的Schema中,HSQLDB默认Schema为
PUBLIC,如果建表时指定了其他Schema,查询时需要携带Schema前缀。 - 表未持久化:如果之前建表的进程没有正常关闭,表结构仅存在于内存中未写入磁盘文件,新连接无法读取到对应表。
修复方案
1. 优化资源关闭逻辑
推荐使用try-with-resources语法自动关闭JDBC资源,无需手动编写finally关闭逻辑,从根源避免空指针问题,修复后的代码示例如下:
import java.sql.*; public class FirstSQLAccess { public static void main(String[] args) { try { Class.forName("org.hsqldb.jdbc.JDBCDriver"); } catch (ClassNotFoundException e) { e.printStackTrace(); return; } // 先替换为数据库目录的绝对路径做验证,确认路径没问题后再调整为相对路径 String jdbcUrl = "jdbc:hsqldb:file:替换为你本地实际的绝对路径/database/firstSQLAccess/;shutdown=true;hsqldb.lock.file=false"; // try-with-resources会自动关闭所有实现AutoCloseable接口的资源 try (Connection con = DriverManager.getConnection(jdbcUrl, "sa", ""); Statement stmt = con.createStatement(); // 查询时加上默认Schema前缀避免Schema匹配问题 ResultSet rs = stmt.executeQuery("SELECT * FROM PUBLIC.PERSON")) { while (rs.next()) { // 注意:如果Name是字符串类型,需把getInt改为getString,此处为原代码的潜在问题 System.out.println("Name: " + rs.getString(1)); } } catch (SQLException throwables) { throwables.printStackTrace(); } } }
2. 验证表持久化状态
打开数据库目录下后缀为.script的文件,搜索是否存在CREATE TABLE PERSON相关语句:
- 如果不存在,说明之前建表操作未持久化,或者连接路径错误指向了空白数据库,确认路径正确后重新建表即可
- 如果存在,确认建表时表名是否用双引号包裹为小写,如果是,查询时需要改为
SELECT * FROM "person"严格匹配大小写
内容的提问来源于stack exchange,提问作者jailbreakTheTesla
相关产品推荐
相关产品推荐

