HSQLDB嵌入式连接数据不保存、ResultSet.next()空指针异常求助
HSQLDB嵌入式数据库数据无法保存&ResultSet空指针问题排查与解决
看起来你遇到了HSQLDB嵌入式模式下的两个棘手问题:数据插进去存不住,查询还会莫名抛出空指针。我帮你拆解下代码里的问题,再给你针对性的解决办法。
问题根源分析
先看你代码里的几个关键漏洞:
- 事务未提交:HSQLDB默认是手动提交事务(
autoCommit=false),你执行完executeUpdate后没调用con.commit(),所有插入操作都停留在内存事务里,一旦连接关闭就会自动回滚,自然查不到任何持久化的数据。 - 异常被静默吞噬:你的
catch (SQLException ex) { }什么都没做,哪怕SQL语法错误、表不存在、连接异常,你都看不到任何错误提示,排查起来完全摸不着头脑。 - 资源未正确关闭:Connection、Statement、ResultSet这些资源都没有手动关闭,不仅会造成资源泄漏,还可能导致事务无法正常收尾。
- 空指针隐患:如果
con.createStatement()失败(比如连接本身没建立成功),sn会是null,这时候调用sn.executeQuery()必然抛出空指针,而你没捕获并输出这个异常,所以会出现莫名其妙的NPE。
解决步骤&修正后的代码
我把你的代码改成符合JDBC规范的版本,一次性解决这些问题:
import java.sql.*; import java.util.logging.Level; import java.util.logging.Logger; public class DataBaseTest { public static void main(String[] args) { // 使用try-with-resources自动关闭连接、Statement、ResultSet(Java 7+支持,无需手动close) try (Connection con = DriverManager.getConnection( "jdbc:hsqldb:file:GestionPiecesDB\\GestionPiece;hsqldb.lock_file=false", "root", "")) { System.out.println("connected"); // 显式设置手动提交(HSQLDB默认就是false,写出来更清晰) con.setAutoCommit(false); // 插入数据并提交事务 try (Statement stmn = con.createStatement()) { int affectedRows = stmn.executeUpdate( "insert into users (nom, nature, mot_passe) values ('admin', 'admin', 'admin')"); System.out.println("插入了 " + affectedRows + " 条数据"); con.commit(); // 关键!提交事务后数据才会持久化到文件 } catch (SQLException ex) { con.rollback(); // 出错时回滚事务,避免脏数据 Logger.getLogger(DataBaseTest.class.getName()).log(Level.SEVERE, "插入数据失败", ex); } // 查询数据 try (Statement sn = con.createStatement(); ResultSet r = sn.executeQuery("select * from users")) { if (r.next()) { System.out.println("查询到数据:" + r.getString("nom")); } else { System.out.println("没有查询到数据"); } } catch (SQLException ex) { Logger.getLogger(DataBaseTest.class.getName()).log(Level.SEVERE, "查询数据失败", ex); } } catch (SQLException e) { Logger.getLogger(DataBaseTest.class.getName()).log(Level.SEVERE, "数据库连接失败", e); } catch (ClassNotFoundException ex) { // 注:JDBC 4.0+无需手动加载驱动,DriverManager会自动扫描类路径下的驱动 Logger.getLogger(DataBaseTest.class.getName()).log(Level.SEVERE, "加载驱动失败", ex); } } }
额外注意事项
- 驱动加载优化:从JDBC 4.0开始,只要HSQLDB的驱动jar在类路径里,
Class.forName("org.hsqldb.jdbcDriver")可以直接省略,DriverManager会自动发现并加载驱动。 - 文件路径检查:嵌入式模式下的数据库文件路径如果是相对路径,要注意程序运行的工作目录,确保
GestionPiecesDB文件夹能被正确创建和访问。 - 自动提交替代方案:如果不需要手动控制事务,可以在获取连接后设置
con.setAutoCommit(true),这样每次执行SQL都会自动提交,但这种方式在多操作场景下风险较高,不推荐。
内容的提问来源于stack exchange,提问作者Fatiha IMOUSSAINE
相关产品推荐
相关产品推荐

