Announcement Announcement Module
Collapse
No announcement yet.
Handling DataAccessException best practices Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Handling DataAccessException best practices

    Hey,
    Well, I have a typical Spring application (Dao, Service facades)
    From best practices point view, is it ok/accepted to handle the DataAccessException and its childs in the service's methods?
    Thanks.

  • #2
    A DAO (or Gateway) is a pattern that is used to encapsulate specific datasource repositories. So your DAOs can talk to a filesystem, a database, an LDAP repository, web service, or any combination.

    I would imagine that Interfaces would be used to implement DAOs. With that in mind, take this scenario; Would it make sense to define method signatures within the interface that throws SQLException to cover for later use, if for now the DAO only needs to talk to a text file?

    To maintain flexibility within the implementation of DAOs I'd suggest that checked exceptions (exceptions that extend Exception) should be wrapped as unchecked exceptions (exceptions that extend RuntimeException).

    I hope this answers your question.


    Shah.

    Comment


    • #3
      DataAcccessException is a RuntimeException so there is no need to declare it in the method signature.
      I inject Spring Daos into services objects which are in turn inject into Struts2 actions or Wicket pages.
      So the best place to handle DataAccessExceptions is S2 actions or Wicket pages (so I will be able to redirect the use to another page for example).
      Am I right?

      Comment


      • #4
        Originally posted by hubaghdadi View Post
        Hey,
        Well, I have a typical Spring application (Dao, Service facades)
        From best practices point view, is it ok/accepted to handle the DataAccessException and its childs in the service's methods?
        Thanks.
        The only factor that should determine where to handle errors in your application is the specific requirements of your application. In other way, based on what behavior of the application you need in case of any errors (including some specific cases), you should decide which module in your application has the sufficient contextual knowledge to handle any specific error, or all errors in general. This generally means that all exceptions in your Middle tier (Services/DAOs) must freely propagate to the application tier (front-end) that would ultimately handle them. To ensure that, as shahnawazshahin has pointed out, all your exceptions must be unchecked (extend RuntimeException.) This means that you may have to catch any checked exceptions in your services, wrap them into clarifying RT exceptions with added messages, and re-thrown - only to be caught and handled by the designated handlers on the front-end, since only the latter would know what exactly the application wants to do with those errors. In some cases, you may even catch, wrap, and re-throw a RTE - if you think you can add valuable information to it on the way. But no matter what, never discard the original exception, never replace the valuable stack trace with your error message, etc. Always keep the full original stack trace and nested exceptions, because they provide the most important info about the source of the error.

        Also, take a look at these discussions:
        http://forum.springframework.org/showthread.php?t=63549
        http://forum.springframework.org/showthread.php?t=54993
        http://forum.springframework.org/showthread.php?t=54711

        P.S. Don't be confused by most Java books and online examples. Unfortunately, most of them present a completely distorted (and just irresponsible) view on error handling. Most of the books go out of their way to justify the existence of checked exceptions in Java, which is - in my view, the most horrible thing that has happened to Java and its community because it has resulted in almost total misunderstanding of error-handling principles among Java programmers. Fortunately, by now, the debate seems to be almost over.
        Last edited by constv; Dec 16th, 2008, 10:28 AM.

        Comment


        • #5
          Originally posted by hubaghdadi View Post
          DataAcccessException is a RuntimeException so there is no need to declare it in the method signature.
          I inject Spring Daos into services objects which are in turn inject into Struts2 actions or Wicket pages.
          So the best place to handle DataAccessExceptions is S2 actions or Wicket pages (so I will be able to redirect the use to another page for example).
          Am I right?
          That's correct. For example, with Struts, you can have a base/abstract action class that will implement the execute method and wrap it into a try/catch/finally. Inside the try you will call an abstract method, like "doExecute" that all your actions will implement. Most actions won't need to do any error-handling there, just let the exceptions bubble up to the handler in the abstract action's "execute". The catch clauses may first handle a couple of specific cases (if you have any that need to be handled distinctly), and end with "catch (Throwable t)" that will contain the generic system error handling such as redirecting to the standard error page.

          Comment


          • #6
            Originally posted by hubaghdadi View Post
            DataAcccessException is a RuntimeException so there is no need to declare it in the method signature.
            Ah, yes. That is correct. I guess my feedback went into another direction, so apologies for that.

            Originally posted by constv
            This means that you may have to catch any checked exceptions in your services, wrap them into clarifying RT exceptions with added messages, and re-thrown - only to be caught and handled by the designated handlers on the front-end, since only the latter would know what exactly the application wants to do with those errors. In some cases, you may even catch, wrap, and re-throw a RTE - if you think you can add valuable information to it on the way. But no matter what, never discard the original exception, never replace the valuable stack trace with your error message, etc. Always keep the full original stack trace and nested exceptions, because they provide the most important info about the source of the error.
            I agree with constv. If possible, write your own RTEs that the Service implementations can we-wrap against if you can (as constv mentioned 'wrap them into clarifying RT exceptions with added messages, and re-thrown'). It makes the exceptions raised more meaningful and easier to trace.


            Again, slightly off topic - here is a post that talks about the best place to logging exceptions (http://forum.springframework.org/showthread.php?t=62654).

            Comment


            • #7
              Again, slightly off topic - here is a post that talks about the best place to logging exceptions (http://forum.springframework.org/showthread.php?t=62654).
              Well, I might slightly disagree with your views here. There is a simpler, and less convoluted - more consolidated - way to log events and errors.

              For exceptions, they should be logged by the handler in the application tier. If you admit that it is the responsibility of the client to handle the error, you should always agree that it is the client's responsibility to decide what it needs for further diagnostics. It is a responsibility and duty of any client to log errors that it receives. The responsibility of the module that throws the error is to provide as much info about the error as possible, not to log anything. Otherwise, you will end up with confusing convoluted log files with tons of duplicate log statements for the same error, when each thrower and re-thrower logs the same error, perhaps adding a layer of detail message. (In some cases, when components may run on remote servers, it is necessary to log errors at the component boundary - to ensure that that the error info is also logged on the remote server where the component is running. That means, each component API catches everything, logs, and re-throws.)

              In any case, logging should be done in an aspect-like fashion. In SWF, you can use a flow listener to capture an ExceptionThrown event, or a state-entry event, etc. You may also put an aspect around your service APIs to log certain things, etc. In any case, event logging should be consolidated, not sprinkled all over your components. NOTE: I am talking about the logging of application events and errors, not debug logging.

              Comment


              • #8
                Originally posted by shahnawazshahin View Post
                Again, slightly off topic - here is a post that talks about the best place to logging exceptions (http://forum.springframework.org/showthread.php?t=62654).
                Its been a while since we last discussed about this, but what I found is that there are cases where the service layer would need to prevent any exceptions that should not be made visible to the Presentation layer. For example, any DAO related exceptions should not be thrown back. This allows for extra security around the solution to try and prevent such exceptions to be potentially be displayed.

                However, if a different exception needs to be thrown to the Presentation layer then the original exception needs to be logged somewhere. Hence the idea of logging in both placed (the Presentation and Service layers).

                I know this is cumbersome, and it is quite possible to prevent such exposure even at the Presentation layer. However, I have seen a number of examples within larger scaled apps where logging at both places is the norm.

                Just a thought.


                Shah.

                Comment


                • #9
                  Originally posted by shahnawazshahin View Post
                  Its been a while since we last discussed about this, but what I found is that there are cases where the service layer would need to prevent any exceptions that should not be made visible to the Presentation layer. For example, any DAO related exceptions should not be thrown back. This allows for extra security around the solution to try and prevent such exceptions to be potentially be displayed.

                  However, if a different exception needs to be thrown to the Presentation layer then the original exception needs to be logged somewhere. Hence the idea of logging in both placed (the Presentation and Service layers).

                  I know this is cumbersome, and it is quite possible to prevent such exposure even at the Presentation layer. However, I have seen a number of examples within larger scaled apps where logging at both places is the norm.

                  Just a thought.


                  Shah.
                  Thanks Shah.
                  It is quite nice of you to take time to share your thought.

                  Comment


                  • #10
                    Originally posted by shahnawazshahin View Post
                    Its been a while since we last discussed about this, but what I found is that there are cases where the service layer would need to prevent any exceptions that should not be made visible to the Presentation layer. For example, any DAO related exceptions should not be thrown back. This allows for extra security around the solution to try and prevent such exceptions to be potentially be displayed.

                    However, if a different exception needs to be thrown to the Presentation layer then the original exception needs to be logged somewhere. Hence the idea of logging in both placed (the Presentation and Service layers).

                    I know this is cumbersome, and it is quite possible to prevent such exposure even at the Presentation layer. However, I have seen a number of examples within larger scaled apps where logging at both places is the norm.

                    Just a thought.


                    Shah.
                    This is fair, Shah. In many cases - specifically, in distributed environments, it is recommended to make sure that the logging is done on remote servers - in addition to the client logging. So, logging of errors that occur in potentially remote components must - absolutely - be logged by the client application, and on each remote server.

                    Comment


                    • #11
                      Handling DataAccessException best practices

                      Originally posted by hubaghdadi View Post
                      DataAcccessException is a RuntimeException so there is no need to declare it in the method signature.
                      I inject Spring Daos into services objects which are in turn inject into Struts2 actions or Wicket pages.
                      So the best place to handle DataAccessExceptions is S2 actions or Wicket pages (so I will be able to redirect the use to another page for example).
                      Am I right?
                      If I don't want to let the DataAcccessException propagte through the Struts Action
                      or spring @Controller (often a good practice), rather catch it inside business
                      method and rethrow MyAppException...then will
                      @Transactional(readOnly=false, rollbackFor=DataAcccessException.class)
                      still work?

                      Comment


                      • #12
                        Originally posted by constv View Post
                        The only factor that should determine where to handle errors in your application is the specific requirements of your application. In other way, based on what behavior of the application you need in case of any errors (including some specific cases), you should decide which module in your application has the sufficient contextual knowledge to handle any specific error, or all errors in general. This generally means that all exceptions in your Middle tier (Services/DAOs) must freely propagate to the application tier (front-end) that would ultimately handle them. To ensure that, as shahnawazshahin has pointed out, all your exceptions must be unchecked (extend RuntimeException.) This means that you may have to catch any checked exceptions in your services, wrap them into clarifying RT exceptions with added messages, and re-thrown - only to be caught and handled by the designated handlers on the front-end, since only the latter would know what exactly the application wants to do with those errors. In some cases, you may even catch, wrap, and re-throw a RTE - if you think you can add valuable information to it on the way. But no matter what, never discard the original exception, never replace the valuable stack trace with your error message, etc. Always keep the full original stack trace and nested exceptions, because they provide the most important info about the source of the error.
                        That is such a valuable comment ! It explains so much. Thanks !

                        Comment

                        Working...
                        X