public void beforeCompletion() {
if (this.jtaTransaction != null) {
// Typically in case of a suspended JTA transaction:
// Remove the Session for the current JTA transaction, but keep the holder.
Session session = this.sessionHolder.removeSession(this.jtaTransaction);
if (session != null) {
if (this.sessionHolder.isEmpty()) {
// No Sessions for JTA transactions bound anymore -> could remove it.
if (TransactionSynchronizationManager.hasResource(this.sessionFactory)) {
// Explicit check necessary because of remote transaction propagation:
// The synchronization callbacks will execute in a different thread
// in such a scenario, as they're triggered by a remote server.
// The best we can do is to leave the SessionHolder bound to the
// thread that originally performed the data access. It will be
// reused when a new data access operation starts on that thread.
TransactionSynchronizationManager.unbindResource(this.sessionFactory);
}
this.holderActive = false;
}
// Do not close a pre-bound Session. In that case, we'll find the
// transaction-specific Session the same as the default Session.
if (session != this.sessionHolder.getSession()) {
SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, this.sessionFactory);
}
else if (this.sessionHolder.getPreviousFlushMode() != null) {
// In case of pre-bound Session, restore previous flush mode.
session.setFlushMode(this.sessionHolder.getPreviousFlushMode());
}
return;
}
}
// We'll only get here if there was no specific JTA transaction to handle.