[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-6607) Exceptions being hidden in JDBCTransation

Lukasz Antoniak (JIRA) noreply at atlassian.com
Thu Mar 1 16:14:50 EST 2012


    [ https://hibernate.onjira.com/browse/HHH-6607?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=45781#comment-45781 ] 

Lukasz Antoniak commented on HHH-6607:
--------------------------------------

Please read my initial comment. There was a defect, but it should not appear in versions 3.6.7 and 4.0.
It's not about test case, but incorrect application versions to which you address this bug.
Updated link: https://github.com/hibernate/hibernate-orm/commit/d4295cc604555c06ed4f2db8cd846f0e47ec04ec (Core changed to ORM).
Method {{JDBCTransaction.notifyLocalSynchsBeforeTransactionCompletion()}} does not exist in version 3.6.6.Final and there is no exception hiding in {{AuditProcess}} class. {{AuditSync}} has been renamed to {{AuditProcess}} long time ago. You can view the current code here: https://github.com/hibernate/hibernate-orm/blob/master/hibernate-envers/src/main/java/org/hibernate/envers/synchronization/AuditProcess.java

> Exceptions being hidden in JDBCTransation
> -----------------------------------------
>
>                 Key: HHH-6607
>                 URL: https://hibernate.onjira.com/browse/HHH-6607
>             Project: Hibernate ORM
>          Issue Type: Bug
>          Components: envers
>    Affects Versions: 3.6.7
>         Environment: The issue happens when the audit schema is different from the primary schema say because of a column change.  The database session is rolled back but the exception isn't thrown up to any levels past the notifyLocalSynchsBeforeTransactionCompletion() so any applications needing to recover from database failures cannot - say rolling back application caches.
> The way to reproduce this is to drop a column in the aud table for any domain object and try to insert the data
>            Reporter: Rich Christy
>            Assignee: Lukasz Antoniak
>
> 2011-08-24 16:00:15,886 ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
> org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
>         at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
>         at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
>         at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
>         at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
>         at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
>         at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
>         at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2242)
>         at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2678)
>         at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
>         at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
>         at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
>         at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
>         at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
>         at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
>         at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
>         at org.hibernate.envers.synchronization.AuditSync.beforeCompletion(AuditSync.java:161)
>         at org.hibernate.transaction.JDBCTransaction.notifyLocalSynchsBeforeTransactionCompletion(JDBCTransaction.java:274)
>         at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:140)
>         at org.openspaces.persistency.hibernate.DefaultHibernateExternalDataSource.executeBulk(DefaultHibernateExternalDataSource.java:107)
>         at com.skyroad.motion.transactionmanager.util.TransactionMirrorExternalDataSource.executeBulk(TransactionMirrorExternalDataSource.java:32)
> What the code is doing in the exception handling of AuditSync.java (5th line from the bottom in the stack track) is rolling back the transaction as far as the hibernate session is concerned and then unconditionally throwing the exception to the next level.  However, the code in notifyLocalSynchsBeforeTransactionCompletion() eating the exception so Gigaspaces isn't aware that it happened.   This would explain why the database writes are rolled back but the space isn't.
>     public void beforeCompletion() {
>         if (workUnits.size() == 0 && undoQueue.size() == 0) {
>             return;
>         }
>                 try {
>                         // see: http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4178431
>                         if (FlushMode.isManualFlushMode(session.getFlushMode()) || session.isClosed()) {
>                                 Session temporarySession = null;
>                                 try {
>                                         temporarySession = session.getFactory().openTemporarySession();
>                                         executeInSession(temporarySession);
>                                         temporarySession.flush();
>                                 } finally {
>                                         if (temporarySession != null) {
>                                                 temporarySession.close();
>                                         }
>                                 }
>                         } else {
>                                 executeInSession(session);
>                                 // Explicity flushing the session, as the auto-flush may have already happened.
>                                 session.flush();
>                         }
>                 } catch (RuntimeException e) {
>                         // Rolling back the transaction in case of any exceptions
>                         //noinspection finally
>             try {
>                 if (session.getTransaction().isActive()) {
>                             session.getTransaction().rollback();
>                 }
>             } finally {
>                 //noinspection ThrowFromFinallyBlock
>                 throw e;
>             }
>                 }
>     }
>         private void notifyLocalSynchsBeforeTransactionCompletion() {
>                 if (synchronizations!=null) {
>                         for ( int i=0; i<synchronizations.size(); i++ ) {
>                                 Synchronization sync = (Synchronization) synchronizations.get(i);
>                                 try {
>                                         sync.beforeCompletion();
>                                 }
>                                 catch (Throwable t) {
>                                         log.error("exception calling user Synchronization", t);
>                                 }
>                         }
>                 }
>         }

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list