请求流程 - Jsf(Backing Bean) - >业务层 - > DAO层(春道)
有些文章建议DAO层捕获所有sql异常并应抛出checked异常。 Business Layer捕获该异常并根据业务规则抛出自定义异常。
我怀疑是春天hibernateTemplate已经将所有异常转换为未经检查的异常为什么我应该从DAO抛出检查异常?
请提出一些好的方法。感谢
答案 0 :(得分:4)
我怀疑是春天hibernateTemplate已经转换了所有异常 进入未经检查的异常为什么我应该抛出检查异常 DAO?
A)hibernateTemplate将特定于基础结构的已检查异常转换为RuntimeExceptions。这很好,您的服务层不应该处理特定于技术的异常。您可能想要抛出的已检查异常将是您自己的层次结构,其名称和抽象对于在平台内跨层传递故障是有意义的。
b)HibernateTemplate(以及JpaTemplate也是如此)不再是推荐的做事方式。从Spring 3开始,应该使用普通的Hibernate(或普通的JPA),事务管理和异常转换只能通过AOP进行。
答案 1 :(得分:1)
在我看来,有两种类型的例外:
违反业务规则会导致预期的异常(例如,如果用户尝试创建已存在的记录,或者用户试图提取的金额超过其帐户中的金额)。
意外的异常是由不可预见的情况引起的(例如,您的数据库爆炸,代码中的错误或无法访问远程服务器)。
应该优雅地处理预期的例外情况(例如,应该很好地告诉用户他需要做一些不同的事情(例如,用较少的钱尝试提款),或者应用程序应该执行一些纠正措施。
在这种情况下,我认为检查异常很有意义,因为它确保特定服务的消费者处理异常。
对于无法恢复的异常(例如,如果数据库已关闭,或者SQL查询格式错误),那么除了记录异常并显示通用的“Something”之外,您所做的远不止这些可怕的错误,请告诉系统管理员“给用户的消息。在这种情况下,异常应保持未选中状态,并在最高级别捕获并写入日志,以后可以对其进行分析以确定是否需要修复错误或是否将更多弹性添加到数据库(备份,故障转移等)
例如,如果你有一个使用HibernateTemplate的DAO,当违反主键时抛出DataIntegrityViolationException
,那么捕获它并将其转换为业务异常是有意义的。但是,将DataAccessException
的所有实例转换为业务异常是没有意义的,因为您无法执行任何操作,例如BadSqlGrammarException
或异常,告诉您特定的表不存在。
希望有所帮助。
答案 2 :(得分:0)
忽略“一些文章”。 - 有时框架不支持您想要的架构。在这种情况下,您有两个选择
如果你没有充分理由遵守规则,那么第二种方式主要是禁食。
顺便说一下:我想有人会发现相反的“一些文章”。 (根本不要使用经过检查的例外情况)
我的个人建议是使用已检查的ecceptions来处理与业务相关的规则,并且针对无法处理的所有技术问题(例如丢失的数据库连接)取消选中。