I'm trying to migrate application which uses unsynchronized persistence context with JTA transaction, from hibernate 4.3.7 to Hibernate 5.0.7, and I found a couple the of issues I can't get my head around. Our entity manager injected as
@PersistenceContext(type = PersistenceContextType.EXTENDED, synchronization = SynchronizationType.UNSYNCHRONIZED)
private EntityManager entityManager;
So I expect to have extended and unsynchronized persistence context. The application uses UNSYNCHRONIZED feature to avoid flushing changes to the entities to the database until we want to do so. Normally, we want to flush changes only after save/persist/remove operations and these methods calling entityManager.joinTransaction();
to explicitly mark current transaction for synchronisation. This is used to work to a certain degree in Hibernate 4.3.7 but stopped in version 5.
For version 5, the Hiberante guys did quite a lot of rewriting, particularly in transaction handling area. From my understanding, hibernate uses session.autoJoinTransactions flag to implement UNSYNCHRONIZED feature. The session will not be flushed (we use default flushMode.AUTO) unless session joined to the transaction. Previously, this flag will be set for a new session as
sessionBuilder.autoJoinTransactions( getTransactionType() != PersistenceUnitTransactionType.JTA );
and in hibernate 5 (EntityManagetImpl line 132)
sessionBuilder.autoJoinTransactions( getSynchronizationType() == SynchronizationType.SYNCHRONIZED );
As we use JTA managed transactions it used to work. But now it does not. It seems that decide the value for autoJoinTransaction
flag based on the SynchronizationType is the right thing to do, but there is one small problem. The persistenceContextTyoe is not propagated to the EntityFactoryImpl methods and therefore the entity manager always created as synchronised. When injecting the entityManager the wildlfy calling first method and not the second one.
@Override
public EntityManager createEntityManager(Map map) {
return internalCreateEntityManager( SynchronizationType.SYNCHRONIZED, map );
}
@Override
public EntityManager createEntityManager(SynchronizationType synchronizationType, Map map) {
errorIfResourceLocalDueToExplicitSynchronizationType();
return internalCreateEntityManager( synchronizationType, map );
}
So my questions: How to inject the instance of entity manager with Unsynchronized persistence context? Why Wildfly
ignores type = PersistenceContextType.EXTENDED
parameter when injecting entity manager? Am I missing something?