H2数据库恢复报错:java.io.FileNotFoundException权限拒绝求助
解决H2数据库恢复时的"Access is denied"错误
结合你的代码和错误日志来看,你在使用H2的Restore工具恢复备份时遇到的权限问题,主要源于参数传递错误,再加上可能存在的数据库连接未完全释放的情况,咱们一步步来解决:
问题根源拆解
Restore.execute参数用错了:
H2的Restore.execute(String sourceDir, String fileName, String targetDbName)方法里,第一个参数sourceDir是备份ZIP文件所在的目录,不是你要恢复到的目标数据库目录。你现在把目标目录./data传给了第一个参数,导致工具错误地尝试从./data读取备份文件,自然触发了权限或文件找不到的错误。- 数据库连接没彻底断开:
虽然你调用了emf.close(),但JPA的EntityManagerFactory关闭后,底层可能还有残留的JDBC连接没释放,导致H2的数据库文件被锁定,没法写入新数据。
修复步骤
1. 修正Restore.execute的参数传递
把备份文件的所在目录作为第一个参数,目标数据库的完整路径(目录+数据库名)作为第三个参数。修改后的代码如下:
public void Restore() { emf.close(); // 主动关闭所有残留的H2连接,避免文件锁定 try { Class.forName("org.h2.Driver"); DriverManager.getConnection("jdbc:h2:./data/mydata;DB_CLOSE_ON_EXIT=TRUE;SHUTDOWN=TRUE"); } catch (Exception e) { e.printStackTrace(); } JFileChooser chooser = new JFileChooser("./backup"); FileNameExtensionFilter filter = new FileNameExtensionFilter("ZIP", "zip"); chooser.setFileFilter(filter); int returnVal = chooser.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { File selectedFile = chooser.getSelectedFile(); String backupDir = selectedFile.getParent(); // 获取备份文件所在的目录 String fileName = selectedFile.getName(); String targetDbPath = "./data/mydata"; // 目标数据库的完整路径(目录+数据库名) Restore.execute(backupDir, fileName, targetDbPath); System.out.println("restore completed"); } }
2. 确保数据库完全关闭
上面代码里的try-catch块是关键:通过带SHUTDOWN=TRUE的连接URL,强制H2数据库关闭,彻底释放文件锁。同时要确保没有其他程序或线程在连接./data/mydata数据库。
3. 检查目录权限
如果还是报错,要确认这两点:
- 当前运行程序的用户对
./data目录有读写权限。 ./data目录已经存在(如果不存在,手动创建它)。
验证
运行修改后的代码,选择./backup目录下的ZIP备份文件,工具会自动把备份恢复到./data/mydata数据库中,这时应该就不会再出现权限拒绝的错误了。
内容的提问来源于stack exchange,提问作者user9753394
相关产品推荐
相关产品推荐

