Results 1 to 8 of 8

Thread: Annotated transactions and exceptions

  1. #1

    Default Annotated transactions and exceptions

    Hello,

    I am using annotations to mark transaction boundaries in my web application using Spring and Hibernate. Note that I am using the versioning capability of Hibernate. I have the business logic in a set of classes whose methods have the Transactional annotation. One of the purposes of my business logic layer is to translate the unchecked DataAccessExceptions into checked exceptions specific to my application, e.g., MyAppException. So I have code that looks like the following:


    @Transactional
    public void saveItem(final Item item)
    {
    try
    {
    itemDao.saveOrUpdate(item);
    }
    catch (final ObjectOptimisticLockingFailureException oolfe)
    {
    throw new MyAppLockException(oolfe);
    }
    catch (final MyAppException dae)
    {
    throw new MyAppException(dae);
    }
    }


    The problem comes in that the ObjectOptimisticLockingFailureException doesn't actually occur until the transaction is being cleaned up, which due to the nature of AOP is outside my try...catch block. The obvious solution is the following:


    public void saveItem(final Item item)
    {
    try
    {
    saveItemInternal(item);
    }
    catch (final ObjectOptimisticLockingFailureException oolfe)
    {
    throw new MyAppLockException(oolfe);
    }
    catch (final MyAppException dae)
    {
    throw new MyAppException(dae);
    }
    }

    @Transactional
    private void saveItemInternal(final Item item)
    {
    itemDao.saveOrUpdate(item);
    }


    However, this seems wrong in that it is a lot of tedious changes that will be easy to screw up. That seems to be against the nature of Spring in general, so I figure I am probably using it wrong.

    Your mission, should you choose to accept it, is to set me straight.

    Thanks,
    Ray

  2. #2
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    I think the problem here is that your try/catch needs to actually be around the transaction or after throwing. I think you can do this with AOP, but I've never tried.
    Last edited by karldmoore; Aug 30th, 2007 at 07:51 AM.
    Barracuda Networks SSL VPN Lead Developer
    http://pramatr.wordpress.com
    http://twitter.com/karldmoore
    http://www.linkedin.com/in/karldmoore
    Any postings are my own opinion, and should not be attributed to my employer or clients.

  3. #3

    Default

    Quote Originally Posted by karldmoore View Post
    I think the problem here is that your try/catch needs to actually be around the transaction or after throwing. I think you can do this with AOP, but I've never tried.
    I agree that that is certainly the issue. I guess I am wondering what others have done in this situation or why they haven't encountered it.

    I'll see what I can find with AOP. I suppose it ought to be possible, what I am doing is similar to the exception translation that Spring does to create DataAccessExceptions.

  4. #4
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Last edited by karldmoore; Aug 30th, 2007 at 07:51 AM.
    Barracuda Networks SSL VPN Lead Developer
    http://pramatr.wordpress.com
    http://twitter.com/karldmoore
    http://www.linkedin.com/in/karldmoore
    Any postings are my own opinion, and should not be attributed to my employer or clients.

  5. #5

    Default

    Thanks for the AOP lead Karl. There is an example in the spring manual (http://static.springframework.org/sp...spectj-example)
    that looks like it will be easily modifiable to my needs.

    The only thing that bugs me about it is using order = 1 to set the precedence of the aspect relative to the @Transactional advice. I found that used in a couple of places so it is probably safe but I did not find the actual value of order for the transaction advice.

  6. #6
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Quote Originally Posted by RayDeCampo View Post
    Thanks for the AOP lead Karl. There is an example in the spring manual (http://static.springframework.org/sp...spectj-example)
    that looks like it will be easily modifiable to my needs.
    Indeed, you might also want to have a look at after throwing advice. That might be useful as well.

    Quote Originally Posted by RayDeCampo View Post
    The only thing that bugs me about it is using order = 1 to set the precedence of the aspect relative to the @Transactional advice. I found that used in a couple of places so it is probably safe but I did not find the actual value of order for the transaction advice.
    http://forum.springframework.org/showthread.php?t=28459
    http://static.springframework.org/sp...ional-settings
    Last edited by karldmoore; Aug 30th, 2007 at 07:50 AM.
    Barracuda Networks SSL VPN Lead Developer
    http://pramatr.wordpress.com
    http://twitter.com/karldmoore
    http://www.linkedin.com/in/karldmoore
    Any postings are my own opinion, and should not be attributed to my employer or clients.

  7. #7

    Default

    Just as a follow-up I was able to get this working using AOP and after throws advice. One nice aspect is that now I do not need to worry about try...catch blocks in my service layer methods, the interceptor handles translating them into the correct checked exceptions. OTOH, it feels a little wrong to have that so detached from the code, but I suspect that is just my discomfort with a new technology (AOP).

    The new service layer code looks like the following:

    Code:
    @Transactional
    public void saveItem(final Item item) throws MyAppException
    {
        itemDao.saveOrUpdate(item);
    }
    Then the interceptor looks like:

    Code:
    @AfterThrowing(pointcut = POINTCUT_EXPRESSION, throwing = "oolfe")
    public void handleException(final ObjectOptimisticLockingFailureException oolfe)
        throws MyAppException
    {
        throw new StaleObjectMyAppException(oolfe);
    }
    
    @AfterThrowing(pointcut = POINTCUT_EXPRESSION, throwing = "dae")
    public void handleException(final DataAccessException dae)
        throws MyAppException
    {
        throw new MyAppException(dae);
    }

  8. #8
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Thanks for posting back Ray, I'm glad you got it all working. I think that's a pretty neat solution IMHO. I know what you mean about the discomfort factor, when you look at the alternatives I makes me feel better .
    Last edited by karldmoore; Aug 30th, 2007 at 07:50 AM.
    Barracuda Networks SSL VPN Lead Developer
    http://pramatr.wordpress.com
    http://twitter.com/karldmoore
    http://www.linkedin.com/in/karldmoore
    Any postings are my own opinion, and should not be attributed to my employer or clients.

Posting Permissions

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