java 数据访问对象 (DAO) 中的方法应该抛出还是捕获其异常?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15233276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:56:23  来源:igfitidea点击:

Should method in data access object (DAO) throw or catch its exception?

javaspringjakarta-eearchitecturedao

提问by Artegon

I have a Java method in data access object. This very simple method inserts two integer values into database.

我在数据访问对象中有一个 Java 方法。这个非常简单的方法将两个整数值插入到数据库中。

public void saveHourMin(int hour, int min) throws SQLException{
psInsert.setInt(1, hour);
psInsert.setInt(2, min);
psInsert.executeUpdate();
}

Should this method, or, generally speaking, any DAO method, throw an exception when SQLException is thrown, or should it catch and log the exception, then inform a user via return code? Which is the right approach for an application using Spring?

这个方法,或者一般来说,任何 DAO 方法应该在抛出 SQLException 时抛出异常,还是应该捕获并记录异常,然后通过返回码通知用户?对于使用 Spring 的应用程序,哪种方法是正确的?

回答by Nathan Hughes

You can't count on the caller to consistently check return codes, you are better off throwing an exception.

您不能指望调用者始终检查返回码,最好抛出异常。

If you throw SQLException then that will be messy, you will probably end up with higher layers either adding "throws Exception" on every method, or just eating exceptions. Neither one of those alternatives are good.

如果你抛出 SQLException 那么这将是一团糟,你最终可能会得到更高的层,或者在每个方法上添加“抛出异常”,或者只是吃异常。这些选择中的任何一个都不好。

The way Spring does it is it supplies an exception translator that takes in the original SQLException and throws a subclass of RuntimeException that includes the original SQLException as a cause and which tries to give as much information about the error as possible, including using vendor error codes to decide which specific subclass to throw. If you utilize any of Spring's jdbcTemplates then you get the exception translation functionality, so you won't need to include any exception-catching or throwing in your data access objects.

Spring 的做法是提供一个异常转换器,该转换器接收原始 SQLException 并抛出 RuntimeException 的子类,该子类包含原始 SQLException 作为原因,并尝试提供有关错误的尽可能多的信息,包括使用供应商错误代码决定抛出哪个特定的子类。如果您使用 Spring 的任何 jdbcTemplates,那么您将获得异常转换功能,因此您不需要在数据访问对象中包含任何异常捕获或抛出。

If you don't want to use Spring, you can catch the SQLException inside the DAO and throw a RuntimeException, including the original SQLException as a cause. There is nothing you can do about most SQLExceptions, you just want to fail fast and get the exception logged.

如果不想使用 Spring,可以在 DAO 内部捕获 SQLException 并抛出 RuntimeException,包括原始 SQLException 作为原因。对于大多数 SQLException,您无能为力,您只想快速失败并记录异常。

回答by TheZuck

I would create a new exception called DAOException, which is NOT a RuntimeException, and force the user of the method to handle such exceptions, with possibly an enum as a member of the DAOException which describes the exception (possibly adding the actual exception inside as an internal exception).

我将创建一个名为 DAOException 的新异常,它不是 RuntimeException,并强制该方法的用户处理此类异常,可能将枚举作为描述异常的 DAOException 的成员(可能在内部添加实际异常作为内部异常)。

So a thrown exception might look like this:

因此抛出的异常可能如下所示:

new DAOException(DAOException.TYPE.SQLE, e)

and the method saveHourMin throws DAOException.

并且方法 saveHourMin 抛出 DAOException。

This way if you have all kinds of problems, it's all under the same kind of exception and you don't have to handle different ones.

这样,如果您遇到各种问题,都属于同一种异常,您不必处理不同的问题。

The reason I suggest using a general exception and not Runtime is because I don't want it to be optional to handle the exception. Whomever calls this method must be aware of the fact that such a problem may occur and provide the relevant handling (even if that means throwing a new RuntimeException, god forbid, but now it's up to them and it's their decision). As a general rule of thumb, I would avoid using RuntimeExceptions, because they make the execution path unclear ("someone will probably catch this somewhere up the execution path or it will kill the app, so it's ok to let it go" does not sound to good to me).

我建议使用一般异常而不是运行时的原因是因为我不希望它是可选的来处理异常。调用此方法的人必须意识到可能会发生此类问题并提供相关处理的事实(即使这意味着抛出新的 RuntimeException,上帝保佑,但现在取决于他们,这是他们的决定)。作为一般的经验法则,我会避免使用 RuntimeExceptions,因为它们使执行路径不清楚(“有人可能会在执行路径的某个地方捕获它,否则它会杀死应用程序,所以可以放手”听起来不是对我好)。

回答by LuckyLuke

I would say no. Catch the SQLException and then throw a RuntimeException or one if descendants. You don't want to pollute your application with data access exceptions. You should not be catching SQLExceptions in the GUI layer for instance. I would not build an application based on return codes either.

我会说不。捕获 SQLException,然后抛出一个 RuntimeException 或一个 if 后代。您不希望数据访问异常污染您的应用程序。例如,您不应该在 GUI 层捕获 SQLExceptions。我也不会基于返回码构建应用程序。

By throwing a RuntimeException you don't force the callers to catch it either.

通过抛出 RuntimeException 您也不会强迫调用者捕获它。