[jboss-jira] [JBoss JIRA] (WFWIP-53) Differences in ORM exception handling in 5.1 vs 5.3

Gail Badner (JIRA) issues at jboss.org
Tue Jul 24 01:14:00 EDT 2018


    [ https://issues.jboss.org/browse/WFWIP-53?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13609484#comment-13609484 ] 

Gail Badner commented on WFWIP-53:
----------------------------------

[~simkam], HHH-12666 was fixed in 5.3.3.

Please try running the tests setting {{hibernate.native_exception_handling_51_compliance=true}}, and let us know if anything is still failing due to changes in exception handling.

> Differences in ORM exception handling in 5.1 vs 5.3
> ---------------------------------------------------
>
>                 Key: WFWIP-53
>                 URL: https://issues.jboss.org/browse/WFWIP-53
>             Project: WildFly WIP
>          Issue Type: Bug
>          Components: JPA
>            Reporter: Martin Simka
>            Assignee: Gail Badner
>            Priority: Blocker
>
> I see tests failing because {{org.hibernate.hql.internal.ast.QuerySyntaxException}} is wrapped by {{java.lang.IllegalArgumentException}}. I know this has been discussed on hibernate-dev mailing list but without any outcome. 
> http://lists.jboss.org/pipermail/hibernate-dev/2018-May/017654.html
> {quote}
> I've been looking at differences in Hibernate exception handling for
> applications that uses "native" (non-JPA) Hibernate when moving from 5.1 to
> 5.3.
> As you know, exception handling changed in 5.2 when hibernate-entitymanager
> was merged into hibernate-core. This change is documented in the 5.2
> migration guide. [1]
> Here is the relevant text:
> "org.hibernate.HibernateException now extends
> javax.persistence.PersistenceExceptions.
> Hibernate methods that "override" methods from their JPA counterparts now
> will also throw various JDK defined RuntimeExceptions (such as
> IllegalArgumentException, IllegalStateException, etc) as required by the
> JPA contract."
> While digging into this, I see that a HibernateException thrown when using
> 5.1 may, in 5.3, be unwrapped, or may be wrapped by a PersistenceException
> (or a subclass), IllegalArgumentException, or IllegalStateException,
> depending on the particular operation being performed when the
> HibernateException is thrown.
> The reason why the exceptions may be wrapped or unwrapped is because
> Hibernate converts exceptions  (via
> AbstractSharedSessionContract#exceptionConverter)
> for JPA operations which may wrap the HibernateException or throw a
> different exception. Hibernate does not convert exceptions from strictly
> "native" operations, so those exceptions remain unwrapped.
> Here are a couple of examples to illustrate:
> 1) A HibernateException (org.hibernate.TransientObjectException) was thrown
> in 5.1. In 5.3, the same condition can result in
> org.hibernate.TransientObjectException
> that is either unwrapped, or wrapped by IllegalStateException. I've pushed
> a test to my fork to illustrate. [2]
> Thrown during Session#save, #saveOrUpdate
> In 5.1: org.hibernate.TransientObjectException (unwrapped)
> In 5.3: org.hibernate.TransientObjectException (unwrapped)
> Thrown during Session#persist, #merge, #flush
> In 5.1, org.hibernate.TransientObjectException (unwrapped)
> In 5.3, org.hibernate.TransientObjectException wrapped by
> IllegalStateException
> 2) A HibernateException thrown when using 5.1 may be wrapped by a
> PersistenceException, even though HibernateException already extends
> PersistenceException.
> For example, see TransactionTimeoutTest#testTransactionTimeoutFailure:
> https://github.com/hibernate/hibernate-orm/blob/master/
> hibernate-core/src/test/java/org/hibernate/test/tm/
> TransactionTimeoutTest.java#L60-L82
> The exception thrown by the test indicates that the transaction timed out.
> This exception is important enough that an application might retry the
> operation, or at least log for future investigation.
> Thrown during Session#persist (or when changed to use Session#merge or
> Session#flush):
> In 5.1: org.hibernate.TransactionException (unwrapped)
> In 5.3: org.hibernate.TransactionException wrapped by javax.persistence.
> PersistenceException
> Thrown if the test is changed to use Session#save or #saveOrUpdate instead:
> In 5.1: org.hibernate.TransactionException (unwrapped)
> In 5.3: org.hibernate.TransactionException (unwrapped)
> Similarly, by adding some logging, I see that HibernateException objects
> can be wrapped by PersistenceException when running the 5.3 hibernate-core
> unit tests. Depending on the context, I see that some of the following
> exceptions can be wrapped or unwrapped.
> org.hibernate.exception.ConstraintViolationException
> org.hibernate.exception.DataException
> org.hibernate.exception.GenericJDBCException
> org.hibernate.exception.SQLGrammarException
> org.hibernate.id.IdentifierGenerationException
> org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException
> org.hibernate.PersistentObjectException
> org.hibernate.PropertyAccessException
> org.hibernate.PropertyValueException
> org.hibernate.TransactionException
> You can see an example using
> org.hibernate.exception.ConstraintViolationException
> at [3].
> In order to deal with these differences, an application could change the
> following (which was appropriate for 5.1):
> try {
>     ...
> }
> catch (HibernateException ex) {
>     procressHibernateException( ex );
> }
> to the following for 5.3:
> try {
>     ...
> }
> catch (PersistenceException | IllegalStateException |
> IllegalArgumentException ex) {
>     if ( HibernateException.class.isInstance( ex ) ) {
>         handleHibernateException( (HibernateException) ex );
>     }
>     else if ( HibernateException.class.isInstance( ex.getCause() ) ) {
>         handleHibernateException( (HibernateException) ex.getCause() );
>     }
> }
> IMO, it's a little clumsy having to deal with both wrapped and unwrapped
> exceptions. It would be better if exceptions were consistently wrapped, or
> consistently unwrapped.
> I haven't had much of a chance to think about how we can deal with this,
> but one thing that comes to mind is to allow an application to choose a
> particular ExceptionConverter implementation. Hibernate would need to be
> changed to always convert exceptions (including for strictly native
> operations) before returning to the application.
> For example, a property, hibernate.exception_converter could be added with
> the following values:
> jpa - default for JPA applications (org.hibernate.internal.
> ExceptionConverterImpl)
> native (or legacy?) - default for native applications  that does not wrap
> HibernateException
> fully-qualified class name that implements ExceptionConverter
> If users have to make changes to exception handling for 5.3, do you think
> they would be willing to change their application to use JPA exceptions
> (i.e., hibernate.exception_converter=jpa)?
> Comments?
> Regards,
> Gail
> [1] https://github.com/hibernate/hibernate-orm/blob/5.2/migration-guide.adoc
> [2] https://github.com/gbadner/hibernate-core/blob/exception-
> compatibility/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/
> ORMTransientObjectExceptionUnitTestCase.java
> [3] https://github.com/gbadner/hibernate-core/blob/exception-
> compatibility/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/
> ORMConstraintViolationExceptionUnitTestCase.java
> {quote}



--
This message was sent by Atlassian JIRA
(v7.5.0#75005)


More information about the jboss-jira mailing list