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

12,207

Solution 1

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.

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.

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.

Solution 2

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.

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

Solution 3

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).

So a thrown exception might look like this:

new DAOException(DAOException.TYPE.SQLE, e)

and the method saveHourMin throws 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).

Share:
12,207
Artegon
Author by

Artegon

Updated on June 04, 2022

Comments

  • Artegon
    Artegon about 2 years

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

    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?

  • Artegon
    Artegon over 11 years
    I use Spring. Could you provide me more information how to solve this in Spring Framework?
  • Nathan Hughes
    Nathan Hughes over 11 years
    @user1315357 start here: static.springsource.org/spring/docs/3.2.x/…. use the jdbc template and you will get access to the exception translation. static.springsource.org/spring/docs/3.2.x/…
  • Nathan Hughes
    Nathan Hughes over 11 years
    @user1315357 also see this tutorial for an idea of how much code using spring jdbc can save you: dzone.com/tutorials/java/spring/spring-jdbc-tutorial-1.html. googling "spring jdbc tutorial" brings up lots of stuff.