在 ContextInitializer 方法中从 schema.sql 文件执行 sql 语句
Executing sql statement from schema.sql file in ContextInitializer method
我试图在 Listener 的 contextInitialized 方法中执行 sql 语句,但是当我 运行 gretty 本地服务器时,它抛出 RuntimeException 错误。我想不通,为什么。当我注释掉 ps.executeQuery();
.
时,它不会 运行 出现任何错误
@Override
public void contextInitialized(ServletContextEvent sce){
ServletContext sc = sce.getServletContext();
DataSource pool = new ConnectionPoolFactory().createConnectionPool();
String sql = "create table test (id int);";
try (Connection conn = pool.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.executeQuery();
} catch (SQLException e) {
throw new RuntimeException();
}
}
“医生,按这里很痛!”
好吧,那就别这样了。
这个:
} catch (SQLException e) {
throw new RuntimeException();
}
总之是疯了。你犯了一个有用的错误,它包括 5 个方便的方面,可以帮助你找出问题所在:
- 异常的实际类型(可以是 SQLException 的子类;例如 'DatabaseNotAvailableException')
- 与之关联的消息
- 精确指向导致它的代码行的堆栈跟踪
- 原因 - 异常可以有原因,它们本身就是异常(好吧,throwables)。原因通常比异常本身更有用。
- 吞噬异常链。这很少有用。
您已决定将它们 全部 扔进垃圾箱,用一个不提供任何有用信息的 RuntimeException 代替它。
不要那样做。
正确的异常处理包括减少对方法的 throws
子句的恐惧。得到一个做 DB 东西的方法,并且这个方法的设计清楚地表明这样做(如果方法被命名为 'query' 或者包含任何明显表明 SQL 的词,答案很清楚:是的,确实如此),那么该方法 应该 声明为 throws SQLException
,例如。
其次,在极少数情况下向前抛出它不起作用,如果你捕获到一个异常,你不想只记录它并继续,并且你不想在没有设置的情况下抛出其他异常首先是一个原因。这是标准的 'I do not know what to do and I do not want to spend any further time on thinking about it' 异常处理程序:
} catch (ThingIDoNotWantToThinkAbout e) {
throw new RuntimeException("Unhandled", e);
}
, e
至关重要,它将实际异常设置为原因,以便您在堆栈跟踪和日志中实际看到它。 非常 常见 e.printStackTrace()
的标准异常处理。 不要这样做 - java 中 90% 的例子都是错误的。这会导致各种问题,因为 'logs' 转到 standarderr(这比让它们转到您正在操作的上下文的异常处理程序要灵活得多。例如,如果编写 Web 处理程序, e.printStackTrace()
只是转储堆栈。向上抛出异常将转储堆栈 和 允许框架添加有关触发问题的请求的信息,并提供合适的 HTTO 状态 500 错误页面。此外,仅通过 运行 printStackTrace,代码将继续执行,这显然不是您想要的:出了点问题 - 盲目继续将保证您的软件默默地做错事,或导致进一步的异常,从而导致一个错误导致数百个堆栈跟踪淹没您的 syserr。
一旦您解决了这里和代码中其他任何地方的这个问题,实际问题很可能会一目了然。 SQL 服务器宕机或 SQL.
语法错误
我试图在 Listener 的 contextInitialized 方法中执行 sql 语句,但是当我 运行 gretty 本地服务器时,它抛出 RuntimeException 错误。我想不通,为什么。当我注释掉 ps.executeQuery();
.
@Override
public void contextInitialized(ServletContextEvent sce){
ServletContext sc = sce.getServletContext();
DataSource pool = new ConnectionPoolFactory().createConnectionPool();
String sql = "create table test (id int);";
try (Connection conn = pool.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.executeQuery();
} catch (SQLException e) {
throw new RuntimeException();
}
}
“医生,按这里很痛!”
好吧,那就别这样了。
这个:
} catch (SQLException e) { throw new RuntimeException(); }
总之是疯了。你犯了一个有用的错误,它包括 5 个方便的方面,可以帮助你找出问题所在:
- 异常的实际类型(可以是 SQLException 的子类;例如 'DatabaseNotAvailableException')
- 与之关联的消息
- 精确指向导致它的代码行的堆栈跟踪
- 原因 - 异常可以有原因,它们本身就是异常(好吧,throwables)。原因通常比异常本身更有用。
- 吞噬异常链。这很少有用。
您已决定将它们 全部 扔进垃圾箱,用一个不提供任何有用信息的 RuntimeException 代替它。
不要那样做。
正确的异常处理包括减少对方法的 throws
子句的恐惧。得到一个做 DB 东西的方法,并且这个方法的设计清楚地表明这样做(如果方法被命名为 'query' 或者包含任何明显表明 SQL 的词,答案很清楚:是的,确实如此),那么该方法 应该 声明为 throws SQLException
,例如。
其次,在极少数情况下向前抛出它不起作用,如果你捕获到一个异常,你不想只记录它并继续,并且你不想在没有设置的情况下抛出其他异常首先是一个原因。这是标准的 'I do not know what to do and I do not want to spend any further time on thinking about it' 异常处理程序:
} catch (ThingIDoNotWantToThinkAbout e) {
throw new RuntimeException("Unhandled", e);
}
, e
至关重要,它将实际异常设置为原因,以便您在堆栈跟踪和日志中实际看到它。 非常 常见 e.printStackTrace()
的标准异常处理。 不要这样做 - java 中 90% 的例子都是错误的。这会导致各种问题,因为 'logs' 转到 standarderr(这比让它们转到您正在操作的上下文的异常处理程序要灵活得多。例如,如果编写 Web 处理程序, e.printStackTrace()
只是转储堆栈。向上抛出异常将转储堆栈 和 允许框架添加有关触发问题的请求的信息,并提供合适的 HTTO 状态 500 错误页面。此外,仅通过 运行 printStackTrace,代码将继续执行,这显然不是您想要的:出了点问题 - 盲目继续将保证您的软件默默地做错事,或导致进一步的异常,从而导致一个错误导致数百个堆栈跟踪淹没您的 syserr。
一旦您解决了这里和代码中其他任何地方的这个问题,实际问题很可能会一目了然。 SQL 服务器宕机或 SQL.
语法错误