public void testLoggingAutoActivate() throws Throwable { assertFalse( "Auto-logging of misuse of the wrapper should be off", BorrowedConnectionProxy.isCallStackTraced()); UserTransaction txn = transactionService.getUserTransaction(); Connection connection; try { txn.begin(); // Dig the proxy out of ... somewhere ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); connection = conHolder.getConnection(); txn.commit(); } catch (Throwable e) { try { txn.rollback(); } catch (Throwable ee) { } throw e; } // Now mess with the connection, which is protected by the Hibernate wrapper try { connection.commit(); fail("Use case should have generated a HibernateException"); } catch (HibernateException e) { // Expected } assertTrue( "Auto-logging of misuse of the wrapper should now be on", BorrowedConnectionProxy.isCallStackTraced()); // Now start a new transaction and we should see logging txn = transactionService.getUserTransaction(); try { txn.begin(); // Dig the proxy out of ... somewhere ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); connection = conHolder.getConnection(); txn.commit(); } catch (Throwable e) { try { txn.rollback(); } catch (Throwable ee) { } throw e; } // Now mess with the connection, which is protected by the Hibernate wrapper try { connection.commit(); fail("Use case should have generated a HibernateException"); } catch (HibernateException e) { // Expected } // Check for error logs }
public Connection getConnection(DataSource dataSource) { ConnectionHolder connectionHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (connectionHolder == null) { return null; } else { return connectionHolder.getConnection(); } }
@Override protected void doBegin(Object transaction, TransactionDefinition definition) { JpaTransactionObject txObject = (JpaTransactionObject) transaction; if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) { throw new IllegalTransactionStateException( "Pre-bound JDBC Connection found! JpaTransactionManager does not support " + "running within DataSourceTransactionManager if told to manage the DataSource itself. " + "It is recommended to use a single JpaTransactionManager for all transactions " + "on a single DataSource, no matter whether JPA or JDBC access."); } try { if (txObject.getEntityManagerHolder() == null || txObject.getEntityManagerHolder().isSynchronizedWithTransaction()) { EntityManager newEm = createEntityManagerForTransaction(); if (logger.isDebugEnabled()) { logger.debug("Opened new EntityManager [" + newEm + "] for JPA transaction"); } txObject.setEntityManagerHolder(new EntityManagerHolder(newEm), true); } EntityManager em = txObject.getEntityManagerHolder().getEntityManager(); // Delegate to JpaDialect for actual transaction begin. final int timeoutToUse = determineTimeout(definition); Object transactionData = getJpaDialect() .beginTransaction( em, new DelegatingTransactionDefinition(definition) { @Override public int getTimeout() { return timeoutToUse; } }); txObject.setTransactionData(transactionData); // Register transaction timeout. if (timeoutToUse != TransactionDefinition.TIMEOUT_DEFAULT) { txObject.getEntityManagerHolder().setTimeoutInSeconds(timeoutToUse); } // Register the JPA EntityManager's JDBC Connection for the DataSource, if set. if (getDataSource() != null) { ConnectionHandle conHandle = getJpaDialect().getJdbcConnection(em, definition.isReadOnly()); if (conHandle != null) { ConnectionHolder conHolder = new ConnectionHolder(conHandle); if (timeoutToUse != TransactionDefinition.TIMEOUT_DEFAULT) { conHolder.setTimeoutInSeconds(timeoutToUse); } if (logger.isDebugEnabled()) { logger.debug( "Exposing JPA transaction as JDBC transaction [" + conHolder.getConnectionHandle() + "]"); } TransactionSynchronizationManager.bindResource(getDataSource(), conHolder); txObject.setConnectionHolder(conHolder); } else { if (logger.isDebugEnabled()) { logger.debug( "Not exposing JPA transaction [" + em + "] as JDBC transaction because JpaDialect [" + getJpaDialect() + "] does not support JDBC Connection retrieval"); } } } // Bind the entity manager holder to the thread. if (txObject.isNewEntityManagerHolder()) { TransactionSynchronizationManager.bindResource( getEntityManagerFactory(), txObject.getEntityManagerHolder()); } txObject.getEntityManagerHolder().setSynchronizedWithTransaction(true); } catch (TransactionException ex) { closeEntityManagerAfterFailedBegin(txObject); throw ex; } catch (Exception ex) { closeEntityManagerAfterFailedBegin(txObject); throw new CannotCreateTransactionException( "Could not open JPA EntityManager for transaction", ex); } }