Page 3 of 4 FirstFirst 1234 LastLast
Results 21 to 30 of 33

Thread: Need advice on exception handling approach

  1. #21

    Default

    goody! I love you compare your own statements with this huge bible that you wrote for me to refer which I know by heart. And yes I do know who Rod johnson is and his relation to spring framework. I also know his relation to interface21. Therefore quote his writings and don't scold me with his name. I would suggest you reread the last para of what you wrote. I never said stored procedures are not good all together. Stored procedures are useful and extremely useful when it comes to complex calculations on values stored in database rather than making 15 different database calls from java code to complete the task. Dang Rod! is it your writing that is making hard for people to understand or is it them?

    Lets get back to scenario, so you want to go through pains of doing a database IO just to know if provided data is dirty data?

    Hummmm, I wonder if Rod Johnson ever mentioned in his book that "Round trips are not good for just to know if provided data would violate RI of database.

  2. #22
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default Back to the original question

    Hi Again Arno,

    Maybe this thread is so long that I forget what it about

    We are talking about a very specific scenario: a unique constraint on a username. Are you suggesting that we should write PL/SQL code in this case? If so, then you are agreeing that simply relying on a database unique constraint is not enough, and you are choosing to implement the rule in PL/SQL rather than Java code; this is more a matter of personal preference. If not, and we simply attempt to save the object and catch the DataIntegrityViolationException, then please explain how to notify the user which input data was incorrect so he can fix it.

    Quote Originally Posted by Arno Werr
    Hi Arthur,
    It's an issue of separation of concerns.
    Whoever wrote PL/SQL code should provide semantically clear exception (if they don't - they do not deserve their salary). Not just obscure db-specific code. PL/SQL has a very advanced exception handling and propagation capabilities. PL/SQL generates semantically clear exception. I can catch it up, unwrap it, and display to the user.
    -Arthur Loder

  3. #23
    Join Date
    Dec 2005
    Location
    U-241
    Posts
    237

    Default

    @Arthur

    Quote Originally Posted by sk
    Hi all,

    Suppose we are implementing the code for "register a new user to Spring forum". And you need to guarantee that username is unique...

    (There is a service layer, a dao layer, and a view layer. Using declarative transaction management.)

    Here is what i thought:

    hmm, i can put a constraint check in database, let Spring throw DataIntegrityViolationException and catch it in the service layer and
    wrap it within a more specific and meaningful exception and throw the new exception.

    Here is the service layer code:
    Code:
        @Transactional
        public void save(User User) {
            try {
                dao.save(user);
            } catch (DataIntegrityViolationException ex) {
                throw new BusinessException("Duplicate username.");
            }
        }
    You might guess what actually happens in this situation; i can't catch the exception, because dao.save(user) would not really save to the database
    (hence the constraint viloation does not manifest) until transaction commits (when the save method exits).

    Any suggestion? What do you think i should do?
    Well, if it is enough for Sammy, it is enough for Arno.
    Spring, it's a wonderful thing...

  4. #24
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    Quote Originally Posted by Arthur Loder
    We are talking about a very specific scenario: a unique constraint on a username. Are you suggesting that we should write PL/SQL code in this case? If so, then you are agreeing that simply relying on a database unique constraint is not enough, and you are choosing to implement the rule in PL/SQL rather than Java code; this is more a matter of personal preference. If not, and we simply attempt to save the object and catch the DataIntegrityViolationException, then please explain how to notify the user which input data was incorrect so he can fix it.
    Arthur,
    Following your effort to pull it back onto the track , it's probably worth noting that there are actually two issues brought up in OP's scenario. One is how to intelligently convert DataIntegrityViolationException to some kind of business exception that is more specific on exactly what went wrong.

    The other one is something more or less caused by the use of declarative transaction, compounded by Hibernate's flush mechanism. In other words, since the declarative transaction code is wrapped around the service method, any DAO exception thrown in that code cannot be caught and converted by the service method. Forcing a flush in the DAO code sounds to me like more of a hack than a solution because to some extent it defeats the purpose of hibernate's smart flushing algorithm. Maybe these are the cases where we should revert back to the good old programmatic transaction try/catch block entirely within the service method?
    --Jing Xue

  5. #25
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Quote Originally Posted by manifoldronin
    Maybe these are the cases where we should revert back to the good old programmatic transaction try/catch block entirely within the service method?
    No, not the bad old days

    I personally would consider programmatic transaction management more hacky than an interceptor based solution as originally proposed, but maybe I have been doing this IoC thing for too long
    Colin Yates
    SpringSource - http://www.springsource.com - Spring Training, Consulting, and Support - "From the Source"
    Please read http://www.springframework.org/documentation
    Co-Author of Expert Spring MVC + Web Flow.

  6. #26
    Join Date
    Dec 2005
    Location
    U-241
    Posts
    237

    Default

    Quote Originally Posted by manifoldronin
    Forcing a flush in the DAO code sounds to me like more of a hack than a solution because to some extent it defeats the purpose of hibernate's smart flushing algorithm.
    Looks like a hack? Maybe. Yet hack recommended by the Hiberntate development team.
    Quote Originally Posted by manifoldronin
    Maybe these are the cases where we should revert back to the good old programmatic transaction try/catch block entirely within the service method?
    Care to elaborate? Exactly how?
    Sammy already is calling from service layer
    Code:
    @Transactional
        public void save(User User) {
            try {
                dao.save(user);
            } catch (DataIntegrityViolationException ex) {
                throw new BusinessException("Duplicate username.");
            }
        }
    and as he puts it
    i can't catch the exception, because dao.save(user) would not really save to the database (hence the constraint viloation does not manifest) until transaction commits (when the save method exits).
    Spring, it's a wonderful thing...

  7. #27
    Join Date
    Jul 2006
    Location
    Philadelphia, PA, USA
    Posts
    341

    Default New Thread Offshoot

    Hi All,

    As Jing pointed out, this branched off into two separate ideas; I started a separate thread to explore the validation and error reporting aspects of persisting an entity in which there may be unique constraint violations.

    -Arthur Loder

  8. #28

    Default

    OK, I am going to take a final stab at this one. primary and foreign keys are for referencial integrity for database itself so that tables doesn't have ghost entries. Like many IT big guns says and we all learned from our experiences, DO NOT USE DATABASE FOR YOUR BUSINESS LOGIC. a duplicate entry should not occure that is a business decision and defined by Business and must be implemented in application. Let database do its own thing for its own good. Do not monkey with it.

  9. #29
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    Quote Originally Posted by yatesco
    No, not the bad old days

    I personally would consider programmatic transaction management more hacky than an interceptor based solution as originally proposed, but maybe I have been doing this IoC thing for too long
    I agree with you - in general, and let's not get into the whole subjective "it's not hacky according to me" thing. I'll elaborate in the reply to Arno's post why I thought programmatic transaction might be better in the case in question.
    --Jing Xue

  10. #30
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    Quote Originally Posted by Arno Werr
    Looks like a hack? Maybe. Yet hack recommended by the Hiberntate development team.
    I have lots of respect and appreciation (at least at professional level) for the hibernate development team for their technical merit and hard work done. However that doesn't mean I do not question, or at least think it through, any recommendation of theirs before "hopping on" . In this particular case, note we are not talking about doing it in just some special cases. If this is the pattern we are to follow to deal with deferred DB exceptions, then any DAO method that can potentially trigger a DB exception at flush-time must explicitly execute a flush() within its body. Maybe "hack" isn't the proper term to describe this situation, but I just still think that it defeats the purpose of hibernate's flushing scheme.

    Quote Originally Posted by Arno Werr
    Care to elaborate? Exactly how?
    Sammy already is calling from service layer
    The reason DataIntegrityViolationException isn't caught in his service method is the commit (hence the flush) doesn't really happen within the service method. In other words, from a caller's perspective, whether the transaction management code is located inside or outside the actual service method should have been irrelevant according to the fundamentals of AOP. And that's why declarative transaction management works perfectly usually - because the caller doesn't feel any difference. Well, that stops being so, when the transaction management code can actually throw some exception that the caller actually would like to catch, now the location of transaction management matters. And that's where we have three choices:

    1. Stop assuming nothing significant is going to happen between DAO.save()'s exit point and the next statement from where DAO.save() is called, and move the try/catch block to the caller code. That means two things: first, repetitive code as it needs to be done everywhere the service method is called. Second, and more importantly, leak of concern, as in "what the heck is your web controller doing catching dao.DataIntegrityViolationException and converting it to a business exception?!".

    2. Move the transaction code to inside the service method. Note that that doesn't necessarily mean you have to do all the plumbing - there is still the nice TransactionTemplate. So, yeah, admittedly it involves more typing and a little bit repetitive code inside every service method, but that's obviously better than the first choice.

    3. Define a pointcut for the exception throwing flow and advice an exception converter. But AFAIK Spring doesn't support that out of box, so it'd have to be done with raw aspectj aspects.
    --Jing Xue

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •