Issue 1:
Alysson Rodrigues opened SPR-9424 and commented

Hibernate 4.1.0.Final isn´t auto flushing during before completion phase when using JTA (CMT) under Spring 3.1.1.RELEASE and JBoss AS 7.1.

I´ve set hibernate.transaction.factory_class to org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory and hibernate.transaction.jta.platform to org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform. My transaction manager bean is a org.springframework.transaction.jta.JtaTransactionManager configured bean.

Then, logging (TRACE mode) shows me the following info:

15:23:58,555 TRACE [org.springframework.transaction.interceptor.TransactionInterceptor] (http--127.0.0.1-8080-1) Completing transaction for...

15:23:58,557 TRACE [org.springframework.transaction.jta.JtaTransactionManager] (http--127.0.0.1-8080-1) Triggering beforeCommit synchronization

15:23:58,558 TRACE [org.springframework.transaction.jta.JtaTransactionManager] (http--127.0.0.1-8080-1) Triggering beforeCompletion synchronization

15:23:58,559 DEBUG [org.springframework.orm.jpa.EntityManagerFactoryUtils] (http--127.0.0.1-8080-1) Closing JPA EntityManager

15:23:58,560 DEBUG [org.springframework.transaction.jta.JtaTransactionManager] (http--127.0.0.1-8080-1) Initiating transaction commit

15:23:58,561 TRACE [org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization] (http--127.0.0.1-8080-1) JTA sync : beforeCompletion()

15:23:58,562 TRACE [org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl] (http--127.0.0.1-8080-1) Transaction before completion callback

15:23:58,564 TRACE [org.hibernate.internal.SessionImpl] (http--127.0.0.1-8080-1) before transaction completion

15:23:58,566 TRACE [org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization] (http--127.0.0.1-8080-1) JTA sync : afterCompletion(3)

15:23:58,567 TRACE [org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl] (http--127.0.0.1-8080-1) Transaction after completion callback [status=3]

15:23:58,568 TRACE [org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl] (http--127.0.0.1-8080-1) after transaction completion

15:23:58,569 DEBUG [org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] (http--127.0.0.1-8080-1) Aggressively releasing JDBC connection

15:23:58,570 TRACE [org.hibernate.internal.SessionImpl] (http--127.0.0.1-8080-1) after transaction completion

15:23:58,571 DEBUG [org.hibernate.ejb.EntityManagerImpl] (http--127.0.0.1-8080-1) Closing entity manager after transaction completion

15:23:58,572 TRACE [org.hibernate.internal.SessionImpl] (http--127.0.0.1-8080-1) Closing session

15:23:58,573 TRACE [org.hibernate.engine.jdbc.internal.LogicalConnectionImpl] (http--127.0.0.1-8080-1) Closing logical connection

15:23:58,574 TRACE [org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler] (http--127.0.0.1-8080-1) Handling invocation of connection method [close]

15:23:58,575 TRACE [org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler] (http--127.0.0.1-8080-1) Invalidating connection handle

15:23:58,576 TRACE [org.hibernate.engine.jdbc.internal.JdbcResourceRegistryImpl] (http--127.0.0.1-8080-1) Closing JDBC container [org.hibernate.engine.jdbc.internal.JdbcResourceRegistryImpl@17072bf]

...

HOWEVER, IF I use org.springframework.orm.jpa.JpaTransactionManager, instead of JtaTransactionManager, adjusting the configurations above, logging shows me:

16:40:36,014 TRACE [org.springframework.transaction.interceptor.TransactionInterceptor] (http--127.0.0.1-8080-1) Completing transaction for...

16:40:36,015 TRACE [org.springframework.orm.jpa.JpaTransactionManager] (http--127.0.0.1-8080-1) Triggering beforeCommit synchronization

16:40:36,015 TRACE [org.springframework.orm.jpa.JpaTransactionManager] (http--127.0.0.1-8080-1) Triggering beforeCompletion synchronization

16:40:36,016 DEBUG [org.springframework.orm.jpa.JpaTransactionManager] (http--127.0.0.1-8080-1) Initiating transaction commit

16:40:36,016 DEBUG [org.springframework.orm.jpa.JpaTransactionManager] (http--127.0.0.1-8080-1) Committing JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl@2d885a]

16:40:36,017 DEBUG [org.hibernate.engine.transaction.spi.AbstractTransactionImpl] (http--127.0.0.1-8080-1) committing

16:40:36,017 TRACE [org.hibernate.internal.SessionImpl] (http--127.0.0.1-8080-1) Automatically flushing session

16:40:36,017 TRACE [org.hibernate.event.internal.AbstractFlushingEventListener] (http--127.0.0.1-8080-1) Flushing session

16:40:36,018 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (http--127.0.0.1-8080-1) Processing flush-time cascades

16:40:36,018 TRACE [org.hibernate.engine.internal.Cascade] (http--127.0.0.1-8080-1) Processing cascade ACTION_PERSIST_ON_FLUSH for: br.gov.tcu.sgos.modelo.entidade.ordemservico.OrdemServico

16:40:36,019 TRACE [org.hibernate.engine.spi.CascadingAction] (http--127.0.0.1-8080-1) Cascading to persist on flush: br.gov.tcu.sgos.modelo.entidade.contrato.Contrato

16:40:36,020 TRACE [org.hibernate.engine.internal.Cascade] (http--127.0.0.1-8080-1) Done processing cascade ACTION_PERSIST_ON_FLUSH for: br.gov.tcu.sgos.modelo.entidade.ordemservico.OrdemServico

16:40:36,021 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (http--127.0.0.1-8080-1) Dirty checking collections

16:40:36,021 TRACE [org.hibernate.event.internal.AbstractFlushingEventListener] (http--127.0.0.1-8080-1) Flushing entities and processing referenced collections

16:40:36,022 TRACE [org.hibernate.persister.entity.AbstractEntityPersister] (http--127.0.0.1-8080-1) br.gov.tcu.sgos.modelo.entidade.ordemservico.OrdemServico.descricao is dirty

16:40:36,022 TRACE [org.hibernate.event.internal.DefaultFlushEntityEventListener] (http--127.0.0.1-8080-1) Found dirty properties [[br.gov.tcu.sgos.modelo.entidade.ordemservico.OrdemServico#5]] : [Ljava.lang.String;@1882506

16:40:36,023 TRACE [org.hibernate.event.internal.DefaultFlushEntityEventListener] (http--127.0.0.1-8080-1) Updating entity: [br.gov.tcu.sgos.modelo.entidade.ordemservico.OrdemServico#5]

16:40:36,024 TRACE [org.hibernate.engine.internal.Versioning] (http--127.0.0.1-8080-1) Incrementing: 2 to 3

16:40:36,026 TRACE [org.hibernate.event.internal.AbstractFlushingEventListener] (http--127.0.0.1-8080-1) Processing unreferenced collections

16:40:36,026 TRACE [org.hibernate.event.internal.AbstractFlushingEventListener] (http--127.0.0.1-8080-1) Scheduling collection removes/(re)creates/updates

16:40:36,027 DEBUG [org.hibernate.event.internal.AbstractFlushingEventListener] (http--127.0.0.1-8080-1) Flushed: 0 insertions, 1 updates, 0 deletions to 1 objects

SO, is something missing? Some additional configuration? Using JpaTransactionaManager everything works as expected, but when using JtaTransactionManager there is no auto flush during the before completion phase.

Could you please help me?

I´m looking forward to hearing good news from you.

Thank you.

Affects: 3.1.1

Issue Links:

#14040 Session not flushed with Hibernate 4.1.3, JTA and Spring transaction management integration ("duplicates")

Issue 2:
Koen Serneels opened SPR-9404 and commented

I have been migrating from hibernate 3.3.x to hibernate 4.1.3-final using Spring 3.1.1-release.

Besides the hibernate specific refactorings (due to API changes) I thought the only changes for the Spring integration were changing packages names:

Use the LocalSessionFactoryBean from the hibernate4 package

Use the HibernateTransactionManger (which we only use for testing) from the hibernate4 package.

As it turned out the migration when smooth and everything was working on a local tomcat.

However, once we ran our app on glassfish with the JtaTransactionManager (I tested it on GF3.1.2) we got a "No Session found for current thread" when obtaining sessionFactory.currentSession().

After checking SpringSessionContext, we learned that if TransactionSynchronizationManager does not return a existing session or SessionHolder, a check

is performed for a jtaSessionContext, which was null.

The fact that no SessionHolder is registered made also sense as this done by the HibernateTransactionManager and we are using the JtaTransactionManager.

So then learned that in case of JTA you have to specify manually how the tx manager/user transaction can be found.

This was done automatically for you in the hibernate3 LocalSessionFactoryBean, but no longer in the hibernate4 LocalSessionFactoryBean.

So to solve this we configured:

hibernate.transaction.jta.platform and set it to SunOneJtaPlatform.

This resolved the "No Session found for current thread" as it initialized the jtaSessionContext with the txmanager provided by the configured JtaPlatform.

However, now it turns out that the hibernate session is not flushed before the transaction is commited and hence no modifications are written to database.

In the supplied sample we have a basic hibernate setup with H2. Next we have a JtaTransactionManager and a transactional facade.

Next we have a test entity having a single property. The facade has two methods, one to store the entity and one to retrieve the entity.

They both marked as @Transactional and if called will run in there own transaction.

The trigger is a plain JEE servlet which retrieves the facade from application context.

First the store method is called (tx1) then the retrieve method is called (tx2).

As you will see with the Spring hibernate4 integration there was nothing saved.

With the hibernate3 integration everything works as expected and the record is saved

(it can be retrieved by the subsequent retrieval transaction)

What is also bizarre is that in hibernate3 modus everything goes via the Spring TransactionSynchronizationManager (even in JTA mode).

Also the current session is bound via a thread local referenced via the synchronization.

This is bound using a SpringSessionSynchronization which will call flush before transaction completion.

All of this is gone with the hibernate4 integration from the moment a JTA environment is detected.

As of then everything goes via the JTA transaction manager, as there where no Spring Transacion management involved.

This could be normal to a certain extend, but it feels odd compared to the way is was done with hibernate3.

I supplied two samples:

hibernate3.zip : this is the working one, deploy it on GF and goto "http://localhost:8080/hibernate3/Persist"

You will see that it stores a record and is able to retrieve it again

hibernate4.zip : the exact same sample as above, but now with hibernate4 and using LocalSessionFactoryBean from the hibernate4 package and the hibernate.transaction.jta.platform set.

You will see that it stores a record and is NOT able to retrieve it.

Both samples have a POM so it should be trivial to build them.

Affects: 3.1.1

Attachments:

hibernate3.zip (7.33 kB)

hibernate4.zip (7.35 kB)

Issue Links:

#14115 Hibernate 4 smart flushing does not work unless CMTTransactionFactory is being specified ("duplicates")

#12571 util:map support for key-types other than String not working ("is duplicated by")

#14060 Spring JtaTransactionManager is not flushing during before completion phase when using Hibernate 4 or Hibernate 3 ("is duplicated by")

5 votes, 4 watchers