@Override protected void cleanupResource( EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) { if (!committed) { // Clear all pending inserts/updates/deletes in the EntityManager. // Necessary for pre-bound EntityManagers, to avoid inconsistent state. resourceHolder.getEntityManager().clear(); } cleanupTransaction(this.transactionData, resourceKey); } }
@Override protected void releaseResource(EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey) { closeEntityManager(resourceHolder.getEntityManager()); } }
private void closeEntityManager() { if (this.timeoutInProgress || this.errorInProgress) { logger.debug("Closing JPA EntityManager after async request timeout/error"); EntityManagerFactoryUtils.closeEntityManager(this.emHolder.getEntityManager()); } }
@Override protected void releaseResource(EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey) { closeEntityManager(resourceHolder.getEntityManager()); }
@Override protected void cleanupResource( EntityManagerHolder resourceHolder, EntityManagerFactory resourceKey, boolean committed) { if (!committed) { // Clear all pending inserts/updates/deletes in the EntityManager. // Necessary for pre-bound EntityManagers, to avoid inconsistent state. resourceHolder.getEntityManager().clear(); } cleanupTransaction(this.transactionData, resourceKey); } }
@Override public boolean isRollbackOnly() { EntityTransaction tx = getEntityManagerHolder().getEntityManager().getTransaction(); return tx.getRollbackOnly(); }
@Override public void flush() { try { getEntityManagerHolder().getEntityManager().flush(); } catch (RuntimeException ex) { throw DataAccessUtils.translateIfNecessary(ex, getJpaDialect()); } }
@Override public void afterCompletion(WebRequest request, @Nullable Exception ex) throws DataAccessException { if (!decrementParticipateCount(request)) { EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.unbindResource(obtainEntityManagerFactory()); logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewInterceptor"); EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager()); } }
@Override protected void doRollback(DefaultTransactionStatus status) { JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction(); if (status.isDebug()) { logger.debug("Rolling back JPA transaction on EntityManager [" + txObject.getEntityManagerHolder().getEntityManager() + "]"); } try { EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); if (tx.isActive()) { tx.rollback(); } } catch (PersistenceException ex) { throw new TransactionSystemException("Could not roll back JPA transaction", ex); } finally { if (!txObject.isNewEntityManagerHolder()) { // Clear all pending inserts/updates/deletes in the EntityManager. // Necessary for pre-bound EntityManagers, to avoid inconsistent state. txObject.getEntityManagerHolder().getEntityManager().clear(); } } }
/** * Close the current transaction's EntityManager. * Called after a transaction begin attempt failed. * @param txObject the current transaction */ protected void closeEntityManagerAfterFailedBegin(JpaTransactionObject txObject) { if (txObject.isNewEntityManagerHolder()) { EntityManager em = txObject.getEntityManagerHolder().getEntityManager(); try { if (em.getTransaction().isActive()) { em.getTransaction().rollback(); } } catch (Throwable ex) { logger.debug("Could not rollback EntityManager after failed transaction begin", ex); } finally { EntityManagerFactoryUtils.closeEntityManager(em); } txObject.setEntityManagerHolder(null, false); } }
@Override protected void doSetRollbackOnly(DefaultTransactionStatus status) { JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction(); if (status.isDebug()) { logger.debug("Setting JPA transaction on EntityManager [" + txObject.getEntityManagerHolder().getEntityManager() + "] rollback-only"); } txObject.setRollbackOnly(); }
public void setRollbackOnly() { EntityTransaction tx = getEntityManagerHolder().getEntityManager().getTransaction(); if (tx.isActive()) { tx.setRollbackOnly(); } if (hasConnectionHolder()) { getConnectionHolder().setRollbackOnly(); } }
@Override public boolean isRollbackOnly() { EntityTransaction tx = getEntityManagerHolder().getEntityManager().getTransaction(); return tx.getRollbackOnly(); }
/** * close the entity manager. * Use it with caution! This is only intended for use with async request, which Spring won't * close the entity manager until the async request is finished. */ public void closeEntityManager() { EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(getEntityManagerFactory()); if (emHolder == null) { return; } logger.debug("Closing JPA EntityManager in EntityManagerUtil"); EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager()); } }
@Override protected void flushResource(EntityManagerHolder resourceHolder) { EntityManager em = resourceHolder.getEntityManager(); if (em instanceof EntityManagerProxy) { EntityManager target = ((EntityManagerProxy) em).getTargetEntityManager(); if (TransactionSynchronizationManager.hasResource(target)) { // ExtendedEntityManagerSynchronization active after joinTransaction() call: // flush synchronization already registered. return; } } try { em.flush(); } catch (RuntimeException ex) { DataAccessException dae; if (this.jpaDialect != null) { dae = this.jpaDialect.translateExceptionIfPossible(ex); } else { dae = convertJpaAccessExceptionIfPossible(ex); } throw (dae != null ? dae : ex); } }
@Override protected void doCommit(DefaultTransactionStatus status) { JpaTransactionObject txObject = (JpaTransactionObject) status.getTransaction(); if (status.isDebug()) { logger.debug("Committing JPA transaction on EntityManager [" + txObject.getEntityManagerHolder().getEntityManager() + "]"); } try { EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit(); } catch (RollbackException ex) { if (ex.getCause() instanceof RuntimeException) { DataAccessException dae = getJpaDialect().translateExceptionIfPossible((RuntimeException) ex.getCause()); if (dae != null) { throw dae; } } throw new TransactionSystemException("Could not commit JPA transaction", ex); } catch (RuntimeException ex) { // Assumably failed to flush changes to database. throw DataAccessUtils.translateIfNecessary(ex, getJpaDialect()); } }
@Override protected Object doGetTransaction() { JpaTransactionObject txObject = new JpaTransactionObject(); txObject.setSavepointAllowed(isNestedTransactionAllowed()); EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(obtainEntityManagerFactory()); if (emHolder != null) { if (logger.isDebugEnabled()) { logger.debug("Found thread-bound EntityManager [" + emHolder.getEntityManager() + "] for JPA transaction"); } txObject.setEntityManagerHolder(emHolder, false); } if (getDataSource() != null) { ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(getDataSource()); txObject.setConnectionHolder(conHolder); } return txObject; }
try { getJpaDialect().releaseJdbcConnection(conHandle, txObject.getEntityManagerHolder().getEntityManager()); EntityManager em = txObject.getEntityManagerHolder().getEntityManager(); if (logger.isDebugEnabled()) { logger.debug("Closing JPA EntityManager [" + em + "] after transaction");
if (!isAsyncStarted(request)) { logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewFilter"); EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
@Test public void testDoGetEntityManagerWithTx() throws Exception { try { EntityManagerFactory factory = mock(EntityManagerFactory.class); EntityManager manager = mock(EntityManager.class); TransactionSynchronizationManager.initSynchronization(); given(factory.createEntityManager()).willReturn(manager); // no tx active assertSame(manager, EntityManagerFactoryUtils.doGetTransactionalEntityManager(factory, null)); assertSame(manager, ((EntityManagerHolder)TransactionSynchronizationManager.unbindResource(factory)).getEntityManager()); } finally { TransactionSynchronizationManager.clearSynchronization(); } assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty()); }