在最后关闭之前使用 hibernate 在 catch 块中抛出异常

发布于 2024-10-10 07:20:52 字数 312 浏览 6 评论 0原文

所以,我想对此进行一些确认。我将用伪代码来解释。

public void myFunc() throws Exception{
 Session session = Hibernate.getSession();
 try{
    //do somthing
 } catch(Exception ex){
  throw ex;
 } finally{
  session.close();
 }
}

因此,如果在 try 块中引发异常,会话将永远不会关闭。它必须等待池连接超时才能关闭,对吗?如果是这样,是否有更好的做法来捕获休眠异常?

So, I want some confirmation on this. I will explain in pseudo code.

public void myFunc() throws Exception{
 Session session = Hibernate.getSession();
 try{
    //do somthing
 } catch(Exception ex){
  throw ex;
 } finally{
  session.close();
 }
}

Therefore, if a exception is thrown in the try block the session will never be closed. It will have to wait for the pooled connection timeout before it closes, right? If so, is is there a better practice to catching exceptions with hibernate?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情丝乱 2024-10-17 07:20:52

Finally 块中的代码始终会执行。因此,无论 Catch 阻止。正如 kem 在评论中建议的那样,您应该尝试在调试器中单步执行此代码,并亲自查看确切的行为。

附带说明一下,您绝对不应该编写 throw ex,因为这会将原始异常的调用堆栈重置为执行此 throw 语句的位置。结果是您丢失了有关异常实际发生位置的相关信息。相反,您应该只使用throw。或者,您可以创建一个新的异常类并将其 InnerException 设置为 ex,但这似乎是徒劳的额外工作,除非您需要向堆栈跟踪添加其他信息。

当然,您上面显示的代码还提出了一个更大的问题:为什么您首先要捕获异常。一旦您将其重写为在 Catch 块中简单地抛出异常,这与您一开始就没有捕获异常是一样的。相反,为什么不完全省略 Catch 块并仅采用 Try-Finally 模式呢?

public void myFunc()
{
    Session session = Hibernate.getSession();
    try
    {
        //do something
    }
    finally
    {
        session.Close();
    }
}

然后,一旦我们确定可以更改代码以实现 Try-Finally 模式,我们就可以更进一步。为什么不直接用 using 语句替换整个 shebang< /a> 会自动为您处理对象吗?

The code in the Finally block is always executed. So, the session will be closed, regardless of whether or not an exception is thrown in the Catch block. As kem suggested in a comment, you should try single-stepping through this code in the debugger and see the exact behavior for yourself.

As a side note, you should never write throw ex because that will reset the call stack of the original exception to the point where this throw statement is executed. The result is that you lose relevant information about where the exception actually occurred. Instead, you should just use throw. Alternatively, you could create a new exception class and set its InnerException to ex, but that seems like extra work for nothing unless you need to add additional information to the stack trace.

Of course, the code you've shown above also raises the bigger question of why you're catching the exception in the first place. Once you've rewritten it to simply throw the exception in the Catch block, that's the same thing as you not catching the exception in the first place. Instead, why not just omit the Catch block altogether and settle for just the Try-Finally pattern?

public void myFunc()
{
    Session session = Hibernate.getSession();
    try
    {
        //do something
    }
    finally
    {
        session.Close();
    }
}

And then once we've established that the code can be altered to implement the Try-Finally pattern instead, we can go one further. Why not just replace the whole shebang with a using statement that takes care of disposing the object for you automatically?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文