Announcement Announcement Module
Collapse
No announcement yet.
Service Layer Exceptions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #46
    Originally posted by al0 View Post
    Sorry, this solultion does not solve original problem - deferred exception.

    It may be thrown not inside DAO method (unless it explicitly calls flush), but only on commit - i.e. after return from service method. So service method has no chances to catch it (unless explicitly flushes pending changes if any).

    There is one more (smaller) problem tied to this solution - it is highly inadvisable to catch Throwable - and not rethrown immediately in a case of Error. Error's Javadoc states not without a reason

    Code:
    An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.
    Regards,
    Oleksandr

    Hmm, I don't like this stuff with deffered exceptions / triggers and such stuff, keep it simple and do it like the last sample posted - looks like what I've done since long time ago.

    Also in serveral books and tutorials both about EJB3/JPA and hibernate this seems to be what's recommended.

    /S

    Comment


    • #47
      You are free to dislike deferred exception, but, unfortunately for you, they are part of the JPA specification (chapter 3.1.1 EntityManager Interface);
      here is excerpt from persist() Javadoc:
      * Make an instance managed and persistent.
      * @param entity
      * @throws EntityExistsException if the entity already exists.
      * (The EntityExistsException may be thrown when the persist
      * operation is invoked, or the EntityExistsException or
      * another PersistenceException may be thrown at flush or
      * commit time.)
      * @throws IllegalArgumentException if not an entity
      Put attention to the part in bold.


      Originally posted by SigmundL View Post
      Hmm, I don't like this stuff with deffered exceptions / triggers and such stuff, keep it simple and do it like the last sample posted - looks like what I've done since long time ago.

      Also in serveral books and tutorials both about EJB3/JPA and hibernate this seems to be what's recommended.

      /S

      Comment


      • #48
        Originally posted by al0 View Post
        You are free to dislike deferred exception, but, unfortunately for you, they are part of the JPA specification (chapter 3.1.1 EntityManager Interface);
        here is excerpt from persist() Javadoc:


        Put attention to the part in bold.
        Sure, it gets thrown when the transaction commits, in our case at the end of the service method annotated by @Transactional.

        Clarification: I hate being troubled by deferred exceptions ;-)

        /S

        Comment


        • #49
          Originally posted by SigmundL View Post
          Sure, it gets thrown when the transaction commits, in our case at the end of the service method annotated by @Transactional.
          It is not exactly so - it may be thrown on any persistence operation between operation that causes this exception and commit (both ends inclusive). It is sole discretion of implementation when to throw it.

          Clarification: I hate being troubled by deferred exceptions ;-)

          /S
          Not only you, but there were good reasons (partially explained in this very thread) to formulate specification in such a way.

          Regards,
          Oleksandr

          Comment


          • #50
            Sorry, I realize I am late to the game on this one, but I was wondering about a little bit different approach. When you have a service that could possibly be exposed to non-java clients as a SOAP based or REST based web service, is it a good approach to include exception conditions the return type? I think that SOAP uses faults, but what about REST based services? So in the case of createUser(), maybe I am returning a CreateUserResponse object which has the created User on success (+ maybe other contextual data), but also contains the error message(s) on failure. The messages could be broken out into system vs. business errors. I ask the question because I have seen a few public web services take this approach. Any thoughts on that approach?

            Comment


            • #51
              It's funny how many developers (myself including) return CreateUserResponse

              More seriously - service layer need not to know how it would be accessed (REST, SOAP, something else...), so it should not have any influence on the exception processing in the service layer. It is responsibility of the presentation layer to convert service layer exceptions into something understandable to the clients. In case of the REST it may be appropriate HTTP status code (http://www.iana.org/assignments/http-status-codes) and some text message. For example in case of "business" exceptions we include the message from exception object itself and for all others just server error message along with some id that allows us easily find detailed info in logs.



              Originally posted by sky33 View Post
              Sorry, I realize I am late to the game on this one, but I was wondering about a little bit different approach. When you have a service that could possibly be exposed to non-java clients as a SOAP based or REST based web service, is it a good approach to include exception conditions the return type? I think that SOAP uses faults, but what about REST based services? So in the case of createUser(), maybe I am returning a CreateUserResponse object which has the created User on success (+ maybe other contextual data), but also contains the error message(s) on failure. The messages could be broken out into system vs. business errors. I ask the question because I have seen a few public web services take this approach. Any thoughts on that approach?

              Comment


              • #52
                That makes sense. I looked at some REST examples and did see how you can return an HTTP status code and in addition return the actual error message in the body.

                I re-read this thread and ended up with a couple more questions based on find/query type methods of services.

                1) Is it advisable to throw some kind of a NotFoundException when you are querying for a single object? Returning null (although I have done it a ton) does not feel right.

                Code:
                User getUser(String id)
                2) When returning a list, it has been my practice to return an empty list for something like the following when no users are found:

                Code:
                List<User> getUsersWithFirstName(String firstName)
                3) When doing batch style requests, how do I signal a not found condition?

                Code:
                List<UserResult> getUsers(String[] ids)
                If I don't want to fail the entire call on one bad user id, should I communciate it in some kind of UserResult or UserResponse object that has the User (or not) and some kind of status/error message?

                What do you think?

                More seriously - service layer need not to know how it would be accessed (REST, SOAP, something else...), so it should not have any influence on the exception processing in the service layer. It is responsibility of the presentation layer to convert service layer exceptions into something understandable to the clients. In case of the REST it may be appropriate HTTP status code (http://www.iana.org/assignments/http-status-codes) and some text message. For example in case of "business" exceptions we include the message from exception object itself and for all others just server error message along with some id that allows us easily find detailed info in logs.

                Comment


                • #53
                  Originally posted by sky33 View Post
                  1) Is it advisable to throw some kind of a NotFoundException when you are querying for a single object? Returning null (although I have done it a ton) does not feel right.
                  Code:
                  User getUser(String id)
                  For me it feels just right. But it depends on an usage context. For more or less generic library it may be advisable to have both versions - basic that returns null and wrapper around it that throws exception. Then user of library may select one that suit his needs.

                  2) When returning a list, it has been my practice to return an empty list ...
                  100% agree.

                  3) When doing batch style requests, how do I signal a not found condition?

                  Code:
                  List<UserResult> getUsers(String[] ids)
                  If I don't want to fail the entire call on one bad user id, should I communciate it in some kind of UserResult or UserResponse object that has the User (or not) and some kind of status/error message?
                  Yes, this situation is more involved. The simplest answer is - it is already communicated. There is no big problem for caller to compare sizes of ids and returned list. And for cases where all users are mandatory, small wrapper method like getAllUsers(String[] ids) may be handy.
                  What do you think?
                  "There is no use in thinking, let jump" As man has said to the monkey

                  Comment


                  • #54
                    Yes, this situation is more involved. The simplest answer is - it is already communicated. There is no big problem for caller to compare sizes of ids and returned list. And for cases where all users are mandatory, small wrapper method like getAllUsers(String[] ids) may be handy.
                    Yeah, this is the case I struggle with. I guess if you can guaruntee that the only condition where a partial list is returned is when the data is not found, then that would work ok. I think I might instead, provide an additional option of returning a single UserResult object that contains the list of users that were found and a list of ids that were not found as a convenience.

                    So on the getAllUsers(String[] ids) you mentioned where finding a match on all ids is mandatory, you would throw some kind of exception listing the id(s) that were not found.

                    Comment


                    • #55
                      Originally posted by sky33 View Post
                      So on the getAllUsers(String[] ids) you mentioned where finding a match on all ids is mandatory, you would throw some kind of exception listing the id(s) that were not found.
                      That's possible, but as for me, it is enought to return what was found and then caller may check who was/were not found.

                      Comment

                      Working...
                      X