Spring Roo
  1. Spring Roo
  2. ROO-182

JPA Exception Translation should be made available as an optional feature

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.0.0.RC1
    • Fix Version/s: 1.0.0.RC2
    • Component/s: PERSISTENCE
    • Labels:
      None

      Description

      The easiest way to support this would be if Roo would provide a small aspect which catches any RuntimeExceptions thrown by the JPA EntityManager and attempt to translate it accordingly.

        Issue Links

          Activity

          Hide
          Jukka Palomäki added a comment -

          By better, I meant more fine-grained (see the javadoc for EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(RuntimeException)). Something along the lines of:

          @Aspect
          @Configurable
          public final class JpaExceptionTranslator {
              
              @Autowired
              private PersistenceExceptionTranslator translator;
              
              @Pointcut("call(* javax.persistence.EntityManager.*(..))")
              public void entityManagerCall() {}
          
              @Pointcut("call(* javax.persistence.Query.*(..))")
              public void queryCall() {}
          
              @AfterThrowing(pointcut = "entityManagerCall() || queryCall()", throwing = "re")
              public void translate(RuntimeException re) {
                  DataAccessException de =  translator.translateExceptionIfPossible(re);
              	if (de != null) {
              		throw de;
              	} else {
              		throw re;
              	}    
              }
          }
          

          I wrote the code from the back of my head, so it might contain (syntactical) errors. It does require Roo to set the jpa vendor adapter as per the provider (Hibernate, OpenJpa, ...).

          Show
          Jukka Palomäki added a comment - By better, I meant more fine-grained (see the javadoc for EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(RuntimeException)). Something along the lines of: @Aspect @Configurable public final class JpaExceptionTranslator { @Autowired private PersistenceExceptionTranslator translator; @Pointcut( "call(* javax.persistence.EntityManager.*(..))" ) public void entityManagerCall() {} @Pointcut( "call(* javax.persistence.Query.*(..))" ) public void queryCall() {} @AfterThrowing(pointcut = "entityManagerCall() || queryCall()" , throwing = "re" ) public void translate(RuntimeException re) { DataAccessException de = translator.translateExceptionIfPossible(re); if (de != null ) { throw de; } else { throw re; } } } I wrote the code from the back of my head, so it might contain (syntactical) errors. It does require Roo to set the jpa vendor adapter as per the provider (Hibernate, OpenJpa, ...).
          Hide
          Jukka Palomäki added a comment -

          The above code would delegate to the appropriate JpaDialect as per the configured JpaVendorAdapter, either through JpaTransactionManager or LocalContainerEntityManagerFactoryBean (both implement PersistenceExceptionTranslator). And now that I think about it, we would have to qualify the autowiring in the above code, because there is more than one bean of type PersistenceExceptionTranslator .

          Show
          Jukka Palomäki added a comment - The above code would delegate to the appropriate JpaDialect as per the configured JpaVendorAdapter, either through JpaTransactionManager or LocalContainerEntityManagerFactoryBean (both implement PersistenceExceptionTranslator). And now that I think about it, we would have to qualify the autowiring in the above code, because there is more than one bean of type PersistenceExceptionTranslator .
          Hide
          Jukka Palomäki added a comment -

          I wish I were able to edit comments. Having re-checked the API, it seems that JpaTransactionManager does not in fact implement PersistenceExceptionTranslator, so the above code might just work "out of the box" without qualifying the autowire.

          Show
          Jukka Palomäki added a comment - I wish I were able to edit comments. Having re-checked the API, it seems that JpaTransactionManager does not in fact implement PersistenceExceptionTranslator, so the above code might just work "out of the box" without qualifying the autowire.
          Hide
          Ben Alex added a comment - - edited

          Jukka, I've opened ROO-255 to address this and explain more thoroughly what is desired. We're very close to releasing 1.0.0.RC2 so I'm unable to make this change so close to release. Please feel free to provide further comments (or a patch if you're particularly keen!) against ROO-255.

          We also tend to prefer using .aj files for AspectJ code (rather than @AspectJ) because it makes it more transparent to users that it's an AspectJ file. This helps them see the extent of AspectJ-specific usage in their project and also causes AJDT to automatically open instead of the Java editor when a user edits the file in Eclipse/STS (and the AJDT editor provides extra features to assist in composing legally-correct aspects). The .aj syntax is also more feature-rich than the @AspectJ syntax, so any complex enhancements desired to the aspect (either by Roo or by end users) won't require the user to back-port the @AspectJ aspect back to an .aj file. Spring can still dependency inject a .aj-defined aspect. Hope this provides some background on why we used an .aj file instead of @AspectJ for this use case.

          Show
          Ben Alex added a comment - - edited Jukka, I've opened ROO-255 to address this and explain more thoroughly what is desired. We're very close to releasing 1.0.0.RC2 so I'm unable to make this change so close to release. Please feel free to provide further comments (or a patch if you're particularly keen!) against ROO-255 . We also tend to prefer using .aj files for AspectJ code (rather than @AspectJ) because it makes it more transparent to users that it's an AspectJ file. This helps them see the extent of AspectJ-specific usage in their project and also causes AJDT to automatically open instead of the Java editor when a user edits the file in Eclipse/STS (and the AJDT editor provides extra features to assist in composing legally-correct aspects). The .aj syntax is also more feature-rich than the @AspectJ syntax, so any complex enhancements desired to the aspect (either by Roo or by end users) won't require the user to back-port the @AspectJ aspect back to an .aj file. Spring can still dependency inject a .aj-defined aspect. Hope this provides some background on why we used an .aj file instead of @AspectJ for this use case.
          Hide
          Jukka Palomäki added a comment -

          > Hope this provides some background on why we used an .aj file instead of @AspectJ for this use case

          Indeed it did. Thanks for the clarification. I'll track ROO-255.

          Show
          Jukka Palomäki added a comment - > Hope this provides some background on why we used an .aj file instead of @AspectJ for this use case Indeed it did. Thanks for the clarification. I'll track ROO-255 .

            People

            • Assignee:
              Ben Alex
              Reporter:
              Stefan Schmidt
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: