[hibernate-commits] Hibernate SVN: r13929 - in sandbox/trunk/jdbc-impl/src: main/java/org/hibernate/jdbc/delegation and 4 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Aug 16 15:34:04 EDT 2007


Author: steve.ebersole at jboss.com
Date: 2007-08-16 15:34:04 -0400 (Thu, 16 Aug 2007)
New Revision: 13929

Added:
   sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/AggressiveReleaseTest.java
Modified:
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCContainer.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCContainerBuilder.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCServices.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/AbstractStatementDelegate.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/ConnectionDelegate.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/ResultSetDelegate.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/BasicJDBCContainer.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/ConnectionObserver.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/LogicalConnectionImpl.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/LogicalConnectionImplementor.java
   sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/util/ExceptionHelper.java
   sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/ConnectionProviderBuilder.java
   sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/BasicDelegationTests.java
   sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/TestingServiceImpl.java
Log:
import ideas from proxy approach + after_statement releases

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCContainer.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCContainer.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCContainer.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -19,18 +19,57 @@
 import java.sql.Statement;
 
 /**
- * JDBCContainer contract
+ * Contract for a JDBCContainer, which acts as a container (or holder) for JDBC objects.
  *
  * @author Steve Ebersole
  */
 public interface JDBCContainer {
+	/**
+	 * Register a JDBC statement with the container.
+	 *
+	 * @param statement The statement to register.
+	 */
 	public void register(Statement statement);
+
+	/**
+	 * Release a statement (un-register it).
+	 *
+	 * @param statement The statement to release.
+	 */
 	public void release(Statement statement);
 
+	/**
+	 * Register a JDBC resultset with the container.
+	 *
+	 * @param resultSet The resultset to register.
+	 */
 	public void register(ResultSet resultSet);
+
+	/**
+	 * Release a resultset (un-register it).
+	 *
+	 * @param resultSet The resultset to release.
+	 */
 	public void release(ResultSet resultSet);
 
+	/**
+	 * Does this container currently have registered resources?
+	 *
+	 * @return True if the container does have registered resources; false otherwise.
+	 */
 	public boolean hasRegisteredResources();
 
+	/**
+	 * Release all registered resources.
+	 */
+	public void releaseResources();
+
+	/**
+	 * Close this container.  Also releases resources, but additionally indicates that
+	 * the container is expected to no longer be used.  As such the implemntation is
+	 * free to render itself unusable.
+	 *
+	 * @see #releaseResources()
+	 */
 	public void close();
 }

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCContainerBuilder.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCContainerBuilder.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCContainerBuilder.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -24,5 +24,10 @@
  * @author Steve Ebersole
  */
 public interface JDBCContainerBuilder {
+	/**
+	 * Build a container.
+	 *
+	 * @return The container.
+	 */
 	public JDBCContainer buildJdbcContainer();
 }

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCServices.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCServices.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/JDBCServices.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -20,13 +20,37 @@
 import org.hibernate.jdbc.util.SQLStatementLogger;
 
 /**
- * Contract for services around JDBC operations.
+ * Contract for services around JDBC operations.  These represent
+ * shared resources, aka not varied by session/use.
  *
  * @author Steve Ebersole
  */
 public interface JDBCServices {
+	/**
+	 * Obtain service for providing JDBC connections.
+	 *
+	 * @return The connection provider.
+	 */
 	public ConnectionProvider getConnectionProvider();
+
+	/**
+	 * Obtain service for building JDBCContainers instances.
+	 *
+	 * @return The JDBCContainer builder.
+	 */
 	public JDBCContainerBuilder getJdbcContainerBuilder();
+
+	/**
+	 * Obtain service for logging SQL statements.
+	 *
+	 * @return The SQL statement logger.
+	 */
 	public SQLStatementLogger getSqlStatementLogger();
+
+	/**
+	 * Obtain service for dealing with exceptions.
+	 *
+	 * @return The exception helper service.
+	 */
 	public ExceptionHelper getExceptionHelper();
 }

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/AbstractStatementDelegate.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/AbstractStatementDelegate.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/AbstractStatementDelegate.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -27,6 +27,7 @@
 import org.hibernate.HibernateException;
 import org.hibernate.jdbc.JDBCServices;
 import org.hibernate.jdbc.JDBCContainer;
+import org.hibernate.jdbc.impl.LogicalConnectionImplementor;
 
 /**
  * AbstractStatementDelegate implementation
@@ -36,15 +37,17 @@
 public abstract class AbstractStatementDelegate implements Statement, StatementWrapperImplementor {
 	private static final Logger log = LoggerFactory.getLogger( AbstractStatementDelegate.class );
 
-	private boolean valid = true;
 	private ConnectionDelegate connectionDelegate;
 	private Statement statement;
+	private boolean valid = true;
+	private final int hashCode;
 
 	private ResultSet currentResultSetDelegate;
 
 	public AbstractStatementDelegate(ConnectionDelegate connectionDelegate, Statement statement) {
 		this.connectionDelegate = connectionDelegate;
 		this.statement = statement;
+		this.hashCode = statement.hashCode();
 		getJdbcContainer().register( this );
 	}
 
@@ -54,11 +57,13 @@
 		}
 	}
 
-	/*package-protected*/ JDBCServices getJdbcServices() {
+	protected JDBCServices getJdbcServices() {
+		errorIfInvalid();
 		return connectionDelegate.getJdbcServices();
 	}
 
-	/*package-protected*/ JDBCContainer getJdbcContainer() {
+	protected JDBCContainer getJdbcContainer() {
+		errorIfInvalid();
 		return connectionDelegate.getJdbcContainer();
 	}
 
@@ -77,7 +82,15 @@
 		valid = false;
 	}
 
+	public String toString() {
+		return super.toString() + "[valid=" + valid + "]";
+	}
 
+	public int hashCode() {
+		return hashCode;
+	}
+
+
 	// special Statement methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 	public Connection getConnection() throws SQLException {
@@ -87,7 +100,9 @@
 
 	public void close() throws SQLException {
 		if ( valid ) {
+			LogicalConnectionImplementor lc = connectionDelegate.getLogicalConnection();
 			getJdbcContainer().release( this );
+			lc.afterStatementExecution();
 		}
 	}
 

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/ConnectionDelegate.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/ConnectionDelegate.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/ConnectionDelegate.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -44,8 +44,9 @@
 public class ConnectionDelegate implements Connection, ConnectionWrapper, ConnectionObserver {
 	private static final Logger log = LoggerFactory.getLogger( ConnectionDelegate.class );
 
+	private LogicalConnectionImplementor logicalConnection;
 	private boolean valid = true;
-	private LogicalConnectionImplementor logicalConnection;
+	private final int hashCode;
 
 	/**
 	 * Builds a connection delegate with the given logical connection.
@@ -56,13 +57,44 @@
 	public ConnectionDelegate(LogicalConnectionImplementor logicalConnection) {
 		this.logicalConnection = logicalConnection;
 		logicalConnection.addObserver( this );
+		this.hashCode = this.logicalConnection.hashCode();
 	}
 
-	/*package-protected*/ JDBCServices getJdbcServices() {
+	/**
+	 * Access to our logical connection.
+	 *
+	 * @return the logical connection
+	 */
+	protected LogicalConnectionImplementor getLogicalConnection() {
+		errorIfInvalid();
+		return logicalConnection;
+	}
+
+	private void errorIfInvalid() {
+		if ( !valid ) {
+			throw new HibernateException( "connection handle is invalid" );
+		}
+	}
+
+	/**
+	 * Provide access to JDBCServices.
+	 * <p/>
+	 * NOTE : package-protected
+	 *
+	 * @return JDBCServices
+	 */
+	JDBCServices getJdbcServices() {
 		return logicalConnection.getJdbcServices();
 	}
 
-	/*package-protected*/ JDBCContainer getJdbcContainer() {
+	/**
+	 * Provide access to JDBCContainer.
+	 * <p/>
+	 * NOTE : package-protected
+	 *
+	 * @return JDBCContainer
+	 */
+	JDBCContainer getJdbcContainer() {
 		return logicalConnection.getJdbcContainer();
 	}
 
@@ -77,12 +109,22 @@
 		return logicalConnection.getConnection();
 	}
 
-	public void physicalConnectionObtained() {
+	/**
+	 * {@inheritDoc}
+	 */
+	public void physicalConnectionObtained(Connection connection) {
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public void physicalConnectionReleased() {
+		log.info( "logical connection releasing its physical connection");
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	public void logicalConnectionClosed() {
 		log.info( "*** logical connection closed ***" );
 		invalidateDelegate();
@@ -94,7 +136,15 @@
 		valid = false;
 	}
 
+	public String toString() {
+		return super.toString() + "[valid=" + valid + "]";
+	}
 
+	public int hashCode() {
+		return hashCode;
+	}
+
+
 	// statement-creation methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 	public Statement createStatement() {

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/ResultSetDelegate.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/ResultSetDelegate.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/delegation/ResultSetDelegate.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -44,41 +44,53 @@
  * @author Steve Ebersole
  */
 public class ResultSetDelegate implements ResultSet, ResultSetWrapperImplementor {
+
+	private AbstractStatementDelegate statementDelegate;
+	private ResultSet resultSet;
 	private boolean valid = true;
-	private AbstractStatementDelegate statementDelegate;
-	private ResultSet wrappedResultSet;
+	private final int hashCode;
 
-	public ResultSetDelegate(AbstractStatementDelegate statementDelegate, ResultSet wrappedResultSet) {
+	public ResultSetDelegate(AbstractStatementDelegate statementDelegate, ResultSet resultSet) {
 		this.statementDelegate = statementDelegate;
-		this.wrappedResultSet = wrappedResultSet;
+		this.resultSet = resultSet;
+		this.hashCode = resultSet.hashCode();
+		statementDelegate.getJdbcContainer().register( this );
 	}
 
-	/*package-protected*/ JDBCServices getJdbcServices() {
+	protected JDBCServices getJdbcServices() {
 		return statementDelegate.getJdbcServices();
 	}
 
-	/*package-protected*/ JDBCContainer getJdbcContainer() {
+	protected JDBCContainer getJdbcContainer() {
 		return statementDelegate.getJdbcContainer();
 	}
 
 	public ResultSet getWrappedResultSetWithoutChecks() {
-		return wrappedResultSet;
+		return resultSet;
 	}
 
 	public ResultSet getWrappedResultSet() {
 		if ( !valid ) {
 			throw new HibernateException( "resultset handle is invalid" );
 		}
-		return wrappedResultSet;
+		return resultSet;
 	}
 
 	public void invalidate() {
 		statementDelegate = null;
-		wrappedResultSet = null;
+		resultSet = null;
 		valid = false;
 	}
 
+	public String toString() {
+		return super.toString() + "[valid=" + valid + "]";
+	}
 
+	public int hashCode() {
+		return hashCode;
+	}
+
+
 	// special ResultSet methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 	public Statement getStatement() throws SQLException {

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/BasicJDBCContainer.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/BasicJDBCContainer.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/BasicJDBCContainer.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -16,20 +16,19 @@
 package org.hibernate.jdbc.impl;
 
 import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.sql.Statement;
-import java.sql.SQLException;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
-import java.util.Map;
 import java.util.Set;
-import java.util.HashSet;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.hibernate.HibernateException;
+import org.hibernate.jdbc.JDBCContainer;
 import org.hibernate.jdbc.util.ExceptionHelper;
-import org.hibernate.jdbc.JDBCContainer;
 
 /**
  * BasicJDBCContainer implementation
@@ -90,7 +89,7 @@
 	}
 
 	public void release(ResultSet resultSet) {
-		log.trace( "releasing result set [" + resultSet + "]" );
+		log.trace( "releasing result set [{}]", resultSet );
 		Statement statement;
 		try {
 			statement = resultSet.getStatement();
@@ -112,8 +111,12 @@
 		return !xref.isEmpty();
 	}
 
-	public void close() {
-		log.trace( "closing JDBC container [" + this + "]" );
+	public void releaseResources() {
+		log.trace( "releasing JDBC container resources [{}]", this );
+		cleanup();
+	}
+
+	private void cleanup() {
 		Iterator statementIterator = xref.keySet().iterator();
 		while ( statementIterator.hasNext() ) {
 			final Statement statement = ( Statement ) statementIterator.next();
@@ -131,10 +134,15 @@
 		xref.clear();
 	}
 
+	public void close() {
+		log.trace( "closing JDBC container [{}]", this );
+		cleanup();
+	}
+
 	protected void close(Statement statement) {
 		log.trace( "closing prepared statement [" + statement + "]" );
 		try {
-			// if we are unable to "clan" the prepared statement,
+			// if we are unable to "clean" the prepared statement,
 			// we do not close it
 			try {
 				if ( statement.getMaxRows() != 0 ) {
@@ -146,13 +154,13 @@
 			}
 			catch( SQLException sqle ) {
 				// there was a problem "cleaning" the prepared statement
-				log.debug( "Exception clearing maxRows/queryTimeout [" + sqle.getMessage() + "]" );
+				log.debug( "Exception clearing maxRows/queryTimeout [{}]", sqle.getMessage() );
 				return; // EARLY EXIT!!!
 			}
 			statement.close();
 		}
 		catch( SQLException sqle ) {
-			log.debug( "Unable to release statement [" + sqle.getMessage() + "]" );
+			log.debug( "Unable to release statement [{}]", sqle.getMessage() );
 		}
 	}
 
@@ -162,7 +170,7 @@
 			resultSet.close();
 		}
 		catch( SQLException e ) {
-			log.debug( "Unable to release result set [" + e.getMessage() + "]" );
+			log.debug( "Unable to release result set [{}]", e.getMessage() );
 		}
 	}
 }

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/ConnectionObserver.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/ConnectionObserver.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/ConnectionObserver.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -15,13 +15,28 @@
  */
 package org.hibernate.jdbc.impl;
 
+import java.sql.Connection;
+
 /**
- * Observer contract
+ * An observer of logical connection events.
  *
  * @author Steve Ebersole
  */
 public interface ConnectionObserver {
-	public void physicalConnectionObtained();
+	/**
+	 * A physical connection was obtained.
+	 *
+	 * @param connection The physical connection just obtained.
+	 */
+	public void physicalConnectionObtained(Connection connection);
+
+	/**
+	 * A physical connection was released.
+	 */
 	public void physicalConnectionReleased();
+
+	/**
+	 * The logical connection was closed.
+	 */
 	public void logicalConnectionClosed();
 }

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/LogicalConnectionImpl.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/LogicalConnectionImpl.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/LogicalConnectionImpl.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -27,9 +27,8 @@
 import org.hibernate.ConnectionReleaseMode;
 import org.hibernate.HibernateException;
 import org.hibernate.JDBCException;
-import org.hibernate.jdbc.impl.ConnectionObserver;
+import org.hibernate.jdbc.JDBCServices;
 import org.hibernate.jdbc.JDBCContainer;
-import org.hibernate.jdbc.JDBCServices;
 
 /**
  * LogicalConnectionImpl implementation
@@ -44,6 +43,7 @@
 	private final JDBCServices jdbcServices;
 	private final JDBCContainer jdbcContainer;
 	private final List observers = new ArrayList();
+	private boolean releasesEnabled = true;
 
 	private final boolean isUserSuppliedConnection;
 	private boolean isClosed;
@@ -52,6 +52,11 @@
 	        Connection userSuppliedConnection,
 	        ConnectionReleaseMode connectionReleaseMode,
 	        JDBCServices jdbcServices) {
+		if ( connectionReleaseMode == ConnectionReleaseMode.AFTER_STATEMENT &&
+				! jdbcServices.getConnectionProvider().supportsAggressiveRelease() ) {
+			log.debug( "connection provider reports to not support aggressive release; overriding" );
+			connectionReleaseMode = ConnectionReleaseMode.AFTER_TRANSACTION;
+		}
 		this.physicalConnection = userSuppliedConnection;
 		this.connectionReleaseMode = connectionReleaseMode;
 		this.jdbcServices = jdbcServices;
@@ -70,13 +75,6 @@
 	/**
 	 * {@inheritDoc}
 	 */
-	public ConnectionReleaseMode getConnectionReleaseMode() {
-		return connectionReleaseMode;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
 	public JDBCContainer getJdbcContainer() {
 		return jdbcContainer;
 	}
@@ -126,12 +124,12 @@
 		log.trace( "closing logical connection" );
 		Connection c = physicalConnection;
 		if ( !isUserSuppliedConnection && physicalConnection != null ) {
+			jdbcContainer.close();
 			releaseConnection();
 		}
 		// not matter what
 		physicalConnection = null;
 		isClosed = true;
-		jdbcContainer.close();
 		for ( Iterator itr = observers.iterator(); itr.hasNext(); ) {
 			( ( ConnectionObserver ) itr.next() ).logicalConnectionClosed();
 		}
@@ -152,15 +150,56 @@
 //	}
 
 	/**
+	 * {@inheritDoc}
+	 */
+	public ConnectionReleaseMode getConnectionReleaseMode() {
+		return connectionReleaseMode;
+	}
+
+	public void afterStatementExecution() {
+		log.trace( "starting after statement execution processing [{}]", connectionReleaseMode );
+		if ( connectionReleaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
+			if ( ! releasesEnabled ) {
+				log.debug( "skipping aggressive release due to manual disabling" );
+				return;
+			}
+			if ( jdbcContainer.hasRegisteredResources() ) {
+				log.debug( "skipping aggressive release due to registered resources" );
+				return;
+			}
+			releaseConnection();
+		}
+	}
+
+	public void afterTransaction() {
+		if ( connectionReleaseMode == ConnectionReleaseMode.AFTER_STATEMENT ||
+				connectionReleaseMode == ConnectionReleaseMode.AFTER_TRANSACTION ) {
+			if ( jdbcContainer.hasRegisteredResources() ) {
+				log.info( "forcing container resource cleanup on transaction completion" );
+				jdbcContainer.releaseResources();
+			}
+			aggressiveRelease();
+		}
+	}
+
+	public void disableReleases() {
+		log.trace( "disabling releases" );
+		releasesEnabled = false;
+	}
+
+	public void enableReleases() {
+		log.trace( "(re)enabling releases" );
+		releasesEnabled = true;
+		afterStatementExecution();
+	}
+
+	/**
 	 * Force aggresive release of the underlying connection.
 	 */
 	public void aggressiveRelease() {
 		if ( isUserSuppliedConnection ) {
 			log.debug( "cannot aggresively release user-supplied connection; skipping" );
 		}
-		else if ( ! getJdbcServices().getConnectionProvider().supportsAggressiveRelease() ) {
-			log.debug( "connection provider reports to not support aggreswsive release; skipping" );
-		}
 		else {
 			log.debug( "aggressively releasing JDBC connection" );
 			if ( physicalConnection != null ) {
@@ -171,7 +210,6 @@
 
 
 	/**
-	 * Obtains a physical connection from the 
 	 * Pysically opens a JDBC Connection.
 	 *
 	 * @throws JDBCException Indicates problem opening a connection
@@ -181,7 +219,7 @@
 		try {
 			physicalConnection = getJdbcServices().getConnectionProvider().getConnection();
 			for ( Iterator itr = observers.iterator(); itr.hasNext(); ) {
-				( ( ConnectionObserver ) itr.next() ).physicalConnectionObtained();
+				( ( ConnectionObserver ) itr.next() ).physicalConnectionObtained( physicalConnection );
 			}
 			log.debug( "obtained JDBC connection" );
 		}
@@ -191,9 +229,9 @@
 	}
 
 	/**
-	 * Releases the physical JDBC connection back to the provider.
+	 * Physically closes the JDBC Connection.
 	 *
-	 * @throws JDBCException Indicates problem releasing the connection
+	 * @throws JDBCException Indicates problem closing a connection
 	 */
 	private void releaseConnection() throws JDBCException {
 		log.debug( "releasing JDBC connection" );
@@ -201,11 +239,11 @@
 			if ( !physicalConnection.isClosed() ) {
 				getJdbcServices().getExceptionHelper().logAndClearWarnings( physicalConnection );
 			}
-			getJdbcServices().getConnectionProvider().closeConnection( physicalConnection );
-			physicalConnection = null;
 			for ( Iterator itr = observers.iterator(); itr.hasNext(); ) {
 				( ( ConnectionObserver ) itr.next() ).physicalConnectionReleased();
 			}
+			getJdbcServices().getConnectionProvider().closeConnection( physicalConnection );
+			physicalConnection = null;
 			log.debug( "released JDBC connection" );
 		}
 		catch (SQLException sqle) {

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/LogicalConnectionImplementor.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/LogicalConnectionImplementor.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/impl/LogicalConnectionImplementor.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -16,24 +16,65 @@
 package org.hibernate.jdbc.impl;
 
 import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.jdbc.JDBCContainer;
 import org.hibernate.jdbc.JDBCServices;
-import org.hibernate.jdbc.JDBCContainer;
-import org.hibernate.jdbc.impl.ConnectionObserver;
 import org.hibernate.jdbc.LogicalConnection;
 
 /**
- * LogicalConnectionImplementor implementation
+ * The "internal" contract for LogicalConnection
  *
  * @author Steve Ebersole
  */
 public interface LogicalConnectionImplementor extends LogicalConnection {
+	/**
+	 * Obtains the JDBC services associated with this logical connection.
+	 *
+	 * @return JDBC services
+	 */
 	public JDBCServices getJdbcServices();
 
-	public ConnectionReleaseMode getConnectionReleaseMode();
-
+	/**
+	 * Obtains the JDBC object container associated with this logical connection.
+	 *
+	 * @return The JDBC object container.
+	 */
 	public JDBCContainer getJdbcContainer();
 
+	/**
+	 * Add an observer interested in notification of connection events.
+	 *
+	 * @param observer The observer.
+	 */
 	public void addObserver(ConnectionObserver observer);
 
-	public void aggressiveRelease();
+	/**
+	 * The release mode under which this logical connection is operating.
+	 *
+	 * @return the release mode.
+	 */
+	public ConnectionReleaseMode getConnectionReleaseMode();
+
+	/**
+	 * Used to signify that a statement has completed execution which may
+	 * indicate that this logical connection need to perform an
+	 * aggressive release of its physical connection.
+	 */
+	public void afterStatementExecution();
+
+	/**
+	 * Used to signify that a transaction has completed which may indicate
+	 * that this logical connection need to perform an aggressive release
+	 * of its physical connection.
+	 */
+	public void afterTransaction();
+
+	/**
+	 * Manually (and termporarily) circumvent aggressive release processing.
+	 */
+	public void disableReleases();
+
+	/**
+	 * Re enable aggressive release processing (after a prior {@link #disableReleases()} call.
+	 */
+	public void enableReleases();
 }

Modified: sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/util/ExceptionHelper.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/util/ExceptionHelper.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/main/java/org/hibernate/jdbc/util/ExceptionHelper.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -24,10 +24,12 @@
 
 import org.hibernate.JDBCException;
 import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.exception.SQLStateConverter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
 import org.hibernate.util.StringHelper;
 
 /**
- * ExceptionHelper implementation
+ * Helper for handling SQLExceptions in various manners.
  *
  * @author Steve Ebersole
  */
@@ -35,31 +37,83 @@
 	public static final String DEFAULT_EXCEPTION_MSG = "SQL Exception";
 	public static final String DEFAULT_WARNING_MSG = "SQL Warning";
 
+	public static final SQLExceptionConverter DEFAULT_CONVERTER = new SQLStateConverter(
+			new ViolatedConstraintNameExtracter() {
+				public String extractConstraintName(SQLException e) {
+					return null;
+				}
+			}
+	);
+
 	private static final Logger log = LoggerFactory.getLogger( ExceptionHelper.class );
 
 	private SQLExceptionConverter sqlExceptionConverter;
 
+	/**
+	 * Create an exception helper with a default exception converter.
+	 */
+	public ExceptionHelper() {
+		sqlExceptionConverter = DEFAULT_CONVERTER;
+	}
+
+	/**
+	 * Create an exception helper with a specific exception converter.
+	 *
+	 * @param sqlExceptionConverter The exception converter to use.
+	 */
 	public ExceptionHelper(SQLExceptionConverter sqlExceptionConverter) {
 		this.sqlExceptionConverter = sqlExceptionConverter;
 	}
 
+	/**
+	 * Access the current exception converter being used internally.
+	 *
+	 * @return The current exception converter.
+	 */
 	public SQLExceptionConverter getSqlExceptionConverter() {
 		return sqlExceptionConverter;
 	}
 
+	/**
+	 * Inject the exception converter to use.
+	 * <p/>
+	 * NOTE : <tt>null</tt> is allowed and signifies to use the default.
+	 *
+	 * @param sqlExceptionConverter The converter to use.
+	 */
 	public void setSqlExceptionConverter(SQLExceptionConverter sqlExceptionConverter) {
-		this.sqlExceptionConverter = sqlExceptionConverter;
+		this.sqlExceptionConverter = ( sqlExceptionConverter == null ? DEFAULT_CONVERTER : sqlExceptionConverter );
 	}
 
+	/**
+	 * Convert an SQLException using the current converter, doing some logging first.
+	 *
+	 * @param sqle The exception to convert
+	 * @param message An error message.
+	 * @return The converted exception
+	 */
 	public JDBCException convert(SQLException sqle, String message) {
 		return convert( sqle, message, "n/a" );
 	}
 
+	/**
+	 * Convert an SQLException using the current converter, doing some logging first.
+	 *
+	 * @param sqle The exception to convert
+	 * @param message An error message.
+	 * @param sql The SQL being executed when the exception occurred
+	 * @return The converted exception
+	 */
 	public JDBCException convert(SQLException sqle, String message, String sql) {
 		logExceptions( sqle, message + " [" + sql + "]" );
 		return sqlExceptionConverter.convert( sqle, message, sql );
 	}
 
+	/**
+	 * Log any {@link SQLWarning}s registered with the connection.
+	 *
+	 * @param connection The connection to check for warnings.
+	 */
 	public void logAndClearWarnings(Connection connection) {
 		if ( log.isWarnEnabled() ) {
 			try {
@@ -80,10 +134,21 @@
 
 	}
 
+	/**
+	 * Log the given (and any nested) warning.
+	 *
+	 * @param warning The warning
+	 */
 	public void logWarnings(SQLWarning warning) {
 		logWarnings( warning, null );
 	}
 
+	/**
+	 * Log the given (and any nested) warning.
+	 *
+	 * @param warning The warning
+	 * @param message The message text to use as a preamble.
+	 */
 	public void logWarnings(SQLWarning warning, String message) {
 		if ( log.isWarnEnabled() ) {
 			if ( log.isDebugEnabled() && warning != null ) {
@@ -103,25 +168,36 @@
 		}
 	}
 
-	public void logExceptions(SQLException ex) {
-		logExceptions( ex, null );
+	/**
+	 * Log the given (and any nested) exception.
+	 *
+	 * @param sqlException The exception to log
+	 */
+	public void logExceptions(SQLException sqlException) {
+		logExceptions( sqlException, null );
 	}
 
-	public void logExceptions(SQLException ex, String message) {
+	/**
+	 * Log the given (and any nested) exception.
+	 *
+	 * @param sqlException The exception to log
+	 * @param message The message text to use as a preamble.
+	 */
+	public void logExceptions(SQLException sqlException, String message) {
 		if ( log.isErrorEnabled() ) {
 			if ( log.isDebugEnabled() ) {
 				message = StringHelper.isNotEmpty( message ) ? message : DEFAULT_EXCEPTION_MSG;
-				log.debug( message, ex );
+				log.debug( message, sqlException );
 			}
-			while ( ex != null ) {
+			while ( sqlException != null ) {
 				StringBuffer buf = new StringBuffer( 30 )
 						.append( "SQL Error: " )
-						.append( ex.getErrorCode() )
+						.append( sqlException.getErrorCode() )
 						.append( ", SQLState: " )
-						.append( ex.getSQLState() );
+						.append( sqlException.getSQLState() );
 				log.warn( buf.toString() );
-				log.error( ex.getMessage() );
-				ex = ex.getNextException();
+				log.error( sqlException.getMessage() );
+				sqlException = sqlException.getNextException();
 			}
 		}
 	}

Modified: sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/ConnectionProviderBuilder.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/ConnectionProviderBuilder.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/ConnectionProviderBuilder.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -28,11 +28,19 @@
  */
 public class ConnectionProviderBuilder {
 	public static ConnectionProvider buildConnectionProvider() {
+		return buildConnectionProvider( false );
+	}
+
+	public static ConnectionProvider buildConnectionProvider(final boolean allowAggressiveRelease) {
 		Properties props = new Properties( null );
 		props.put( Environment.DRIVER, "org.hsqldb.jdbcDriver" );
 		props.put( Environment.URL, "jdbc:hsqldb:mem:target/test/db/hsqldb/hibernate" );
 		props.put( Environment.USER, "sa" );
-		DriverManagerConnectionProvider connectionProvider = new DriverManagerConnectionProvider();
+		DriverManagerConnectionProvider connectionProvider = new DriverManagerConnectionProvider() {
+			public boolean supportsAggressiveRelease() {
+				return allowAggressiveRelease;
+			}
+		};
 		connectionProvider.configure( props );
 		return connectionProvider;
 	}

Added: sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/AggressiveReleaseTest.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/AggressiveReleaseTest.java	                        (rev 0)
+++ sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/AggressiveReleaseTest.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details. You should have received a
+ * copy of the GNU Lesser General Public License, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.jdbc.delegation;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+import org.hibernate.jdbc.impl.ConnectionObserver;
+import org.hibernate.jdbc.impl.LogicalConnectionImpl;
+import org.hibernate.ConnectionReleaseMode;
+
+/**
+ * AggressiveReleaseTest implementation
+ *
+ * @author Steve Ebersole
+ */
+public class AggressiveReleaseTest {
+	private static final Logger log = LoggerFactory.getLogger( AggressiveReleaseTest.class );
+	private TestingServiceImpl services = new TestingServiceImpl();
+
+	private static class ConnectionCounter implements ConnectionObserver {
+		public int obtainCount = 0;
+		public int releaseCount = 0;
+
+		public void physicalConnectionObtained(Connection connection) {
+			obtainCount++;
+		}
+
+		public void physicalConnectionReleased() {
+			releaseCount++;
+		}
+
+		public void logicalConnectionClosed() {
+		}
+	}
+
+	@BeforeClass
+	protected void create() {
+		log.debug( "starting @BeforeClass" );
+		services.prepare( true );
+	}
+
+	@AfterClass
+	protected void destroy() {
+		services.release();
+	}
+
+	@BeforeMethod
+	protected void setUpSchema() throws SQLException {
+		log.debug( "starting @BeforeMethod" );
+		Connection connection = null;
+		Statement stmnt = null;
+		try {
+			connection = services.getConnectionProvider().getConnection();
+			stmnt = connection.createStatement();
+			stmnt.execute( "drop table SANDBOX_JDBC_TST if exists" );
+			stmnt.execute( "create table SANDBOX_JDBC_TST ( ID integer, NAME varchar(100) )" );
+		}
+		finally {
+			if ( stmnt != null ) {
+				try {
+					stmnt.close();
+				}
+				catch ( SQLException ignore ) {
+					log.warn( "could not close statement used to set up schema", ignore );
+				}
+			}
+			if ( connection != null ) {
+				try {
+					connection.close();
+				}
+				catch ( SQLException ignore ) {
+					log.warn( "could not close connection used to set up schema", ignore );
+				}
+			}
+		}
+	}
+
+	@AfterMethod
+	protected void tearDownSchema() throws SQLException {
+		Connection connection = null;
+		Statement stmnt = null;
+		try {
+			connection = services.getConnectionProvider().getConnection();
+			stmnt = connection.createStatement();
+			stmnt.execute( "drop table SANDBOX_JDBC_TST if exists" );
+		}
+		finally {
+			if ( stmnt != null ) {
+				try {
+					stmnt.close();
+				}
+				catch ( SQLException ignore ) {
+					log.warn( "could not close statement used to set up schema", ignore );
+				}
+			}
+			if ( connection != null ) {
+				try {
+					connection.close();
+				}
+				catch ( SQLException ignore ) {
+					log.warn( "could not close connection used to set up schema", ignore );
+				}
+			}
+		}
+	}
+
+	@Test
+	public void testBasicRelease() {
+		LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
+		Connection proxiedConnection = new ConnectionDelegate( logicalConnection );
+		ConnectionCounter observer = new ConnectionCounter();
+		logicalConnection.addObserver( observer );
+
+		try {
+			PreparedStatement ps = proxiedConnection.prepareStatement( "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )" );
+			ps.setLong( 1, 1 );
+			ps.setString( 2, "name" );
+			ps.execute();
+			assertTrue( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 1, observer.obtainCount );
+			assertEquals( 0, observer.releaseCount );
+			ps.close();
+			assertFalse( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 1, observer.obtainCount );
+			assertEquals( 1, observer.releaseCount );
+		}
+		catch ( SQLException sqle ) {
+			fail( "incorrect exception type : sqlexception" );
+		}
+		finally {
+			logicalConnection.close();
+		}
+
+		assertFalse( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+	}
+
+	@Test
+	public void testReleaseCircumventedByHeldResources() {
+		LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
+		Connection proxiedConnection = new ConnectionDelegate( logicalConnection );
+		ConnectionCounter observer = new ConnectionCounter();
+		logicalConnection.addObserver( observer );
+
+		try {
+			PreparedStatement ps = proxiedConnection.prepareStatement( "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )" );
+			ps.setLong( 1, 1 );
+			ps.setString( 2, "name" );
+			ps.execute();
+			assertTrue( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 1, observer.obtainCount );
+			assertEquals( 0, observer.releaseCount );
+			ps.close();
+			assertFalse( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 1, observer.obtainCount );
+			assertEquals( 1, observer.releaseCount );
+
+			// open a result set and hold it open...
+			ps = proxiedConnection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
+			ps.executeQuery();
+			assertTrue( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 2, observer.obtainCount );
+			assertEquals( 1, observer.releaseCount );
+
+			// open a second result set
+			PreparedStatement ps2 = proxiedConnection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
+			ps2.execute();
+			assertTrue( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 2, observer.obtainCount );
+			assertEquals( 1, observer.releaseCount );
+			// and close it...
+			ps2.close();
+			// the release should be circumvented...
+			assertTrue( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 2, observer.obtainCount );
+			assertEquals( 1, observer.releaseCount );
+
+			// let the close of the logical connection below release all resources (hopefully)...
+		}
+		catch ( SQLException sqle ) {
+			fail( "incorrect exception type : sqlexception" );
+		}
+		finally {
+			logicalConnection.close();
+		}
+
+		assertFalse( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+		assertEquals( 2, observer.obtainCount );
+		assertEquals( 2, observer.releaseCount );
+	}
+
+	@Test
+	public void testReleaseCircumventedManually() {
+		LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_STATEMENT, services );
+		Connection proxiedConnection = new ConnectionDelegate( logicalConnection );
+		ConnectionCounter observer = new ConnectionCounter();
+		logicalConnection.addObserver( observer );
+
+		try {
+			PreparedStatement ps = proxiedConnection.prepareStatement( "insert into SANDBOX_JDBC_TST( ID, NAME ) values ( ?, ? )" );
+			ps.setLong( 1, 1 );
+			ps.setString( 2, "name" );
+			ps.execute();
+			assertTrue( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 1, observer.obtainCount );
+			assertEquals( 0, observer.releaseCount );
+			ps.close();
+			assertFalse( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 1, observer.obtainCount );
+			assertEquals( 1, observer.releaseCount );
+
+			// disable releases...
+			logicalConnection.disableReleases();
+
+			// open a result set...
+			ps = proxiedConnection.prepareStatement( "select * from SANDBOX_JDBC_TST" );
+			ps.executeQuery();
+			assertTrue( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 2, observer.obtainCount );
+			assertEquals( 1, observer.releaseCount );
+			// and close it...
+			ps.close();
+			// the release should be circumvented...
+			assertFalse( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+			assertEquals( 2, observer.obtainCount );
+			assertEquals( 1, observer.releaseCount );
+
+			// let the close of the logical connection below release all resources (hopefully)...
+		}
+		catch ( SQLException sqle ) {
+			fail( "incorrect exception type : sqlexception" );
+		}
+		finally {
+			logicalConnection.close();
+		}
+
+		assertFalse( logicalConnection.getJdbcContainer().hasRegisteredResources() );
+		assertEquals( 2, observer.obtainCount );
+		assertEquals( 2, observer.releaseCount );
+	}
+}

Modified: sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/BasicDelegationTests.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/BasicDelegationTests.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/BasicDelegationTests.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -41,7 +41,7 @@
 
 	@BeforeClass
 	protected void create() {
-		services.prepare();
+		services.prepare( false );
 	}
 
 	@AfterClass
@@ -50,18 +50,29 @@
 	}
 
 	@Test
+	public void testExceptionHandling() {
+		LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_TRANSACTION, services );
+		ConnectionDelegate connection = new ConnectionDelegate( logicalConnection );
+		try {
+			connection.prepareStatement( "select count(*) from NON_EXISTENT" ).executeQuery();
+		}
+		catch ( SQLException sqle ) {
+			fail( "incorrect exception type : sqlexception" );
+		}
+		catch ( JDBCException ok ) {
+			// expected outcome
+		}
+		finally {
+			logicalConnection.close();
+		}
+	}
+
+	@Test
 	public void testBasicJdbcUsage() throws JDBCException {
 		LogicalConnectionImpl logicalConnection = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_TRANSACTION, services );
 		ConnectionDelegate connection = new ConnectionDelegate( logicalConnection );
 
 		try {
-			try {
-				connection.prepareStatement( "select count(*) from NON_EXISTENT" ).executeQuery();
-			}
-			catch ( JDBCException ok ) {
-				// expected outcome
-			}
-
 			Statement stmnt = connection.createStatement();
 			stmnt.execute( "drop table SANDBOX_JDBC_TST if exists" );
 			stmnt.execute( "create table SANDBOX_JDBC_TST ( ID integer, NAME varchar(100) )" );

Modified: sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/TestingServiceImpl.java
===================================================================
--- sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/TestingServiceImpl.java	2007-08-16 19:02:03 UTC (rev 13928)
+++ sandbox/trunk/jdbc-impl/src/test/java/org/hibernate/jdbc/delegation/TestingServiceImpl.java	2007-08-16 19:34:04 UTC (rev 13929)
@@ -15,8 +15,6 @@
  */
 package org.hibernate.jdbc.delegation;
 
-import java.sql.SQLException;
-
 import org.hibernate.jdbc.JDBCServices;
 import org.hibernate.jdbc.JDBCContainerBuilder;
 import org.hibernate.jdbc.ConnectionProviderBuilder;
@@ -24,8 +22,6 @@
 import org.hibernate.jdbc.util.SQLStatementLogger;
 import org.hibernate.jdbc.util.ExceptionHelper;
 import org.hibernate.connection.ConnectionProvider;
-import org.hibernate.exception.SQLStateConverter;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
 
 /**
  * TestingServiceImpl implementation
@@ -38,18 +34,10 @@
 	private JDBCContainerBuilder jdbcContainerBuilder;
 	private ExceptionHelper exceptionHelper;
 
-	public void prepare() {
-		connectionProvider = ConnectionProviderBuilder.buildConnectionProvider();
+	public void prepare(boolean allowAggressiveRelease) {
+		connectionProvider = ConnectionProviderBuilder.buildConnectionProvider( allowAggressiveRelease );
 		sqlStatementLogger = new SQLStatementLogger( true );
-		exceptionHelper = new ExceptionHelper(
-				new SQLStateConverter(
-						new ViolatedConstraintNameExtracter() {
-							public String extractConstraintName(SQLException e) {
-								return null;
-							}
-						}
-				)
-		);
+		exceptionHelper = new ExceptionHelper();
 		jdbcContainerBuilder = new JDBCContainerBuilder() {
 			public JDBCContainer buildJdbcContainer() {
 				return new DelegateJDBCContainer( exceptionHelper );




More information about the hibernate-commits mailing list