Author: steve.ebersole(a)jboss.com
Date: 2007-08-17 00:04:34 -0400 (Fri, 17 Aug 2007)
New Revision: 13931
Added:
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/AbstractBatchImpl.java
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/Batch.java
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchBuilder.java
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchObserver.java
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchingBatch.java
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/NonBatchingBatch.java
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/BasicBatchTest.java
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/TestingServiceImpl.java
Log:
initial batch support on top of proxies
Added:
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/AbstractBatchImpl.java
===================================================================
---
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/AbstractBatchImpl.java
(rev 0)
+++
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/AbstractBatchImpl.java 2007-08-17
04:04:34 UTC (rev 13931)
@@ -0,0 +1,145 @@
+/*
+ * 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.batch;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.jdbc.JDBCServices;
+import org.hibernate.jdbc.impl.LogicalConnectionImplementor;
+import org.hibernate.jdbc.proxy.ProxyBuilder;
+
+/**
+ * AbstractBatchImpl implementation
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractBatchImpl implements Batch {
+ private static final Logger log = LoggerFactory.getLogger( AbstractBatchImpl.class );
+
+ private Object key;
+ private LogicalConnectionImplementor logicalConnection;
+ private Connection connectionProxy;
+ private LinkedHashMap statements = new LinkedHashMap();
+ private LinkedHashSet observers = new LinkedHashSet();
+
+ protected AbstractBatchImpl(Object key, LogicalConnectionImplementor logicalConnection)
{
+ this.key = key;
+ this.logicalConnection = logicalConnection;
+ this.connectionProxy = ProxyBuilder.buildConnection( logicalConnection );
+ }
+
+ protected abstract void doExecuteBatch();
+
+ protected JDBCServices getJdbcServices() {
+ return logicalConnection.getJdbcServices();
+ }
+
+ protected LinkedHashMap getStatements() {
+ return statements;
+ }
+
+ public final Object getKey() {
+ return key;
+ }
+
+ public final PreparedStatement getBatchStatement(String sql, boolean callable) {
+ PreparedStatement statement = ( PreparedStatement ) statements.get( sql );
+ if ( statement == null ) {
+ statement = buildBatchStatement( sql, callable );
+ statements.put( sql, statement );
+ }
+ else {
+ log.debug( "reusing batch statement" );
+ logicalConnection.getJdbcServices().getSqlStatementLogger().logStatement( sql );
+ }
+ return statement;
+ }
+
+ private PreparedStatement buildBatchStatement(String sql, boolean callable) {
+ try {
+ if ( callable ) {
+ return connectionProxy.prepareCall( sql );
+ }
+ else {
+ return connectionProxy.prepareStatement( sql );
+ }
+ }
+ catch ( SQLException sqle ) {
+ log.error( "sqlexception escaped proxy", sqle );
+ throw logicalConnection.getJdbcServices().getExceptionHelper().convert( sqle,
"could not prepare batch statement", sql );
+ }
+ }
+
+ public final void execute() {
+ notifyObserversExplicitExecution();
+ if ( statements.isEmpty() ) {
+ return;
+ }
+ try {
+ try {
+ doExecuteBatch();
+ }
+ finally {
+ releaseStatements();
+ }
+ }
+ finally {
+ statements.clear();
+ }
+ }
+
+ private void releaseStatements() {
+ Iterator itr = getStatements().entrySet().iterator();
+ while ( itr.hasNext() ) {
+ final Map.Entry entry = ( Map.Entry ) itr.next();
+ try {
+ final PreparedStatement statement = ( PreparedStatement ) entry.getValue();
+ statement.close();
+ }
+ catch ( SQLException e ) {
+ log.error( "unable to release batch statement..." );
+ log.error( "sqlexception escaped proxy", e );
+ }
+ }
+ }
+
+ public void addObserver(BatchObserver observer) {
+ observers.add( observer );
+ }
+
+ private void notifyObserversExplicitExecution() {
+ Iterator itr = observers.iterator();
+ while ( itr.hasNext() ) {
+ ( ( BatchObserver ) itr.next() ).batchExplicitlyExecuted();
+ }
+ }
+
+ protected void notifyObserversImplicitExecution() {
+ Iterator itr = observers.iterator();
+ while ( itr.hasNext() ) {
+ ( ( BatchObserver ) itr.next() ).batchImplicitlyExecuted();
+ }
+ }
+}
Added: sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/Batch.java
===================================================================
--- sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/Batch.java
(rev 0)
+++ sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/Batch.java 2007-08-17
04:04:34 UTC (rev 13931)
@@ -0,0 +1,34 @@
+/*
+ * 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.batch;
+
+import java.sql.PreparedStatement;
+
+import org.hibernate.jdbc.Expectation;
+
+/**
+ * Conceptually models a batch, but unlike directly in JDBC, here we add the ability to
+ * batch together multiple statements at a time.
+ *
+ * @author Steve Ebersole
+ */
+public interface Batch {
+ public Object getKey();
+ public void addObserver(BatchObserver observer);
+ public PreparedStatement getBatchStatement(String sql, boolean callable);
+ public void addToBatch(Expectation expectation);
+ public void execute();
+}
Added: sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchBuilder.java
===================================================================
--- sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchBuilder.java
(rev 0)
+++
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchBuilder.java 2007-08-17
04:04:34 UTC (rev 13931)
@@ -0,0 +1,52 @@
+/*
+ * 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.batch;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.jdbc.impl.LogicalConnectionImplementor;
+
+/**
+ * BatchBuilder implementation
+ *
+ * @author Steve Ebersole
+ */
+public class BatchBuilder {
+ private static final Logger log = LoggerFactory.getLogger( BatchBuilder.class );
+
+ // todo : eventually have this take the Settings; this form is needed for testing
because Settings is final :(
+
+ private int size;
+
+ public BatchBuilder() {
+ }
+
+ public BatchBuilder(int size) {
+ this.size = size;
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
+
+ public Batch buildBatch(Object key, LogicalConnectionImplementor logicalConnection) {
+ log.trace( "building batch [size={}]", size );
+ return size > 1
+ ? new BatchingBatch( key, logicalConnection, size )
+ : new NonBatchingBatch( key, logicalConnection );
+ }
+}
Added: sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchObserver.java
===================================================================
--- sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchObserver.java
(rev 0)
+++
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchObserver.java 2007-08-17
04:04:34 UTC (rev 13931)
@@ -0,0 +1,26 @@
+/*
+ * 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.batch;
+
+/**
+ * BatchObserver contract
+ *
+ * @author Steve Ebersole
+ */
+public interface BatchObserver {
+ public void batchExplicitlyExecuted();
+ public void batchImplicitlyExecuted();
+}
Added: sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchingBatch.java
===================================================================
--- sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchingBatch.java
(rev 0)
+++
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/BatchingBatch.java 2007-08-17
04:04:34 UTC (rev 13931)
@@ -0,0 +1,117 @@
+/*
+ * 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.batch;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.jdbc.Expectation;
+import org.hibernate.jdbc.impl.LogicalConnectionImplementor;
+import org.hibernate.HibernateException;
+
+/**
+ * BatchingBatch implementation
+ *
+ * @author Steve Ebersole
+ */
+public class BatchingBatch extends AbstractBatchImpl {
+ private static final Logger log = LoggerFactory.getLogger( BatchingBatch.class );
+
+ private final int batchSize;
+ private Expectation[] expectations;
+ private int batchPosition;
+
+ public BatchingBatch(Object key, LogicalConnectionImplementor logicalConnection, int
batchSize) {
+ super( key, logicalConnection );
+ this.batchSize = batchSize;
+ this.expectations = new Expectation[ batchSize ];
+ }
+
+ public void addToBatch(Expectation expectation) {
+ if ( !expectation.canBeBatched() ) {
+ throw new HibernateException( "attempting to batch an operation which cannot be
batched" );
+ }
+ Iterator itr = getStatements().entrySet().iterator();
+ while ( itr.hasNext() ) {
+ final Map.Entry entry = ( Map.Entry ) itr.next();
+ try {
+ final PreparedStatement statement = ( PreparedStatement ) entry.getValue();
+ statement.addBatch();
+ }
+ catch ( SQLException e ) {
+ log.error( "sqlexception escaped proxy", e );
+ throw getJdbcServices().getExceptionHelper()
+ .convert( e, "could not perform addBatch", ( String ) entry.getKey() );
+ }
+ }
+ expectations[ batchPosition++ ] = expectation;
+ if ( batchPosition == batchSize ) {
+ notifyObserversImplicitExecution();
+ doExecuteBatch();
+ }
+ }
+
+ protected void doExecuteBatch() {
+ if ( batchPosition == 0 ) {
+ log.debug( "no batched statements to execute" );
+ }
+ else {
+ if ( log.isDebugEnabled() ) {
+ log.debug( "Executing batch size: " + batchPosition );
+ }
+
+ try {
+ Iterator itr = getStatements().entrySet().iterator();
+ while ( itr.hasNext() ) {
+ final Map.Entry entry = ( Map.Entry ) itr.next();
+ try {
+ final PreparedStatement statement = ( PreparedStatement ) entry.getValue();
+ checkRowCounts( statement.executeBatch(), statement );
+ }
+ catch ( SQLException e ) {
+ log.error( "sqlexception escaped proxy", e );
+ throw getJdbcServices().getExceptionHelper()
+ .convert( e, "could not perform addBatch", ( String ) entry.getKey()
);
+ }
+ }
+ }
+ catch ( RuntimeException re ) {
+ log.error( "Exception executing batch [{}]", re.getMessage() );
+ throw re;
+ }
+ finally {
+ batchPosition = 0;
+ }
+
+ }
+ }
+
+ private void checkRowCounts(int[] rowCounts, PreparedStatement ps) throws SQLException,
HibernateException {
+ int numberOfRowCounts = rowCounts.length;
+ if ( numberOfRowCounts != batchPosition ) {
+ log.warn( "JDBC driver did not return the expected number of row counts" );
+ }
+ for ( int i = 0; i < numberOfRowCounts; i++ ) {
+ expectations[i].verifyOutcome( rowCounts[i], ps, i );
+ }
+ }
+
+}
Added:
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/NonBatchingBatch.java
===================================================================
--- sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/NonBatchingBatch.java
(rev 0)
+++
sandbox/trunk/jdbc-proxy/src/main/java/org/hibernate/jdbc/batch/NonBatchingBatch.java 2007-08-17
04:04:34 UTC (rev 13931)
@@ -0,0 +1,62 @@
+/*
+ * 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.batch;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.jdbc.Expectation;
+import org.hibernate.jdbc.impl.LogicalConnectionImplementor;
+
+/**
+ * NonBatchingBatch implementation
+ *
+ * @author Steve Ebersole
+ */
+public class NonBatchingBatch extends AbstractBatchImpl {
+ private static final Logger log = LoggerFactory.getLogger( NonBatchingBatch.class );
+
+ protected NonBatchingBatch(Object key, LogicalConnectionImplementor logicalConnection)
{
+ super( key, logicalConnection );
+ }
+
+ public void addToBatch(Expectation expectation) {
+ notifyObserversImplicitExecution();
+ Iterator itr = getStatements().entrySet().iterator();
+ while ( itr.hasNext() ) {
+ final Map.Entry entry = ( Map.Entry ) itr.next();
+ try {
+ final PreparedStatement statement = ( PreparedStatement ) entry.getValue();
+ final int rowCount = statement.executeUpdate();
+ expectation.verifyOutcome( rowCount, statement, 0 );
+ }
+ catch ( SQLException e ) {
+ log.error( "sqlexception escaped proxy", e );
+ throw getJdbcServices().getExceptionHelper()
+ .convert( e, "could not execute batch statement", ( String )
entry.getKey() );
+ }
+ }
+ }
+
+ protected void doExecuteBatch() {
+ // nothing to do
+ }
+}
Added:
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/BasicBatchTest.java
===================================================================
--- sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/BasicBatchTest.java
(rev 0)
+++
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/BasicBatchTest.java 2007-08-17
04:04:34 UTC (rev 13931)
@@ -0,0 +1,219 @@
+/*
+ * 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.batch;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import static org.testng.Assert.*;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.jdbc.Expectations;
+import org.hibernate.jdbc.impl.LogicalConnectionImpl;
+import org.hibernate.jdbc.proxy.ProxyBuilder;
+
+/**
+ * BasicBatchTest implementation
+ *
+ * @author Steve Ebersole
+ */
+public class BasicBatchTest {
+ private static final Logger log = LoggerFactory.getLogger( BasicBatchTest.class );
+
+ private TestingServiceImpl services = new TestingServiceImpl();
+
+ private static class BatchCounter implements BatchObserver {
+ public int explicitBatchCount;
+ public int implicitBatchCount;
+
+ public void batchExplicitlyExecuted() {
+ explicitBatchCount++;
+ }
+
+ public void batchImplicitlyExecuted() {
+ implicitBatchCount++;
+ }
+ }
+
+ @BeforeClass
+ protected void create() {
+ services.prepare( false );
+ }
+
+ @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 testBatchingBatches() throws SQLException {
+ LogicalConnectionImpl lc = new LogicalConnectionImpl( null,
ConnectionReleaseMode.AFTER_TRANSACTION, services );
+ BatchBuilder batchBuilder = new BatchBuilder( 2 );
+
+ // test an explicit batch execution...
+ Batch batch = batchBuilder.buildBatch( this, lc );
+ BatchCounter counter = new BatchCounter();
+ batch.addObserver( counter );
+ PreparedStatement ps = batch.getBatchStatement( "insert into SANDBOX_JDBC_TST( ID,
NAME ) values ( ?, ? )", false );
+ ps.setLong( 1, 1 );
+ ps.setString( 2, "name" );
+ batch.addToBatch( Expectations.BASIC );
+ assertTrue( lc.getJdbcContainer().hasRegisteredResources() );
+ assertEquals( 0, counter.explicitBatchCount );
+ assertEquals( 0, counter.implicitBatchCount );
+ batch.execute();
+ assertEquals( 1, getRowCount() );
+ assertFalse( lc.getJdbcContainer().hasRegisteredResources() );
+ assertEquals( 1, counter.explicitBatchCount );
+ assertEquals( 0, counter.implicitBatchCount );
+
+ lc.close();
+ lc = new LogicalConnectionImpl( null, ConnectionReleaseMode.AFTER_TRANSACTION, services
);
+
+ // test an implicit batch execution...
+ batch = batchBuilder.buildBatch( this, lc );
+ counter = new BatchCounter();
+ batch.addObserver( counter );
+ ps = batch.getBatchStatement( "insert into SANDBOX_JDBC_TST( ID, NAME ) values (
?, ? )", false );
+ ps.setLong( 1, 2 );
+ ps.setString( 2, "me" );
+ assertTrue( lc.getJdbcContainer().hasRegisteredResources() );
+ batch.addToBatch( Expectations.BASIC );
+ assertTrue( lc.getJdbcContainer().hasRegisteredResources() );
+ assertEquals( 0, counter.explicitBatchCount );
+ assertEquals( 0, counter.implicitBatchCount );
+ ps.setLong( 1, 3 );
+ ps.setString( 2, "you" );
+ // this should force execution of the batch...
+ batch.addToBatch( Expectations.BASIC );
+ assertEquals( 3, getRowCount() );
+ assertEquals( 0, counter.explicitBatchCount );
+ assertEquals( 1, counter.implicitBatchCount );
+ batch.execute();
+ assertEquals( 3, getRowCount() );
+ assertFalse( lc.getJdbcContainer().hasRegisteredResources() );
+ assertEquals( 1, counter.explicitBatchCount );
+ assertEquals( 1, counter.implicitBatchCount );
+ lc.close();
+ }
+
+ private int getRowCount() throws SQLException {
+ LogicalConnectionImpl lc = new LogicalConnectionImpl( null,
ConnectionReleaseMode.AFTER_TRANSACTION, services );
+ try {
+ Connection conn = ProxyBuilder.buildConnection( lc );
+ ResultSet rs = conn.createStatement().executeQuery( "select count(*) from
SANDBOX_JDBC_TST" );
+ assert true == rs.next();
+ return rs.getInt( 1 );
+ }
+ finally {
+ lc.close();
+ }
+ }
+
+ @Test
+ public void testNonBatchingBatches() throws SQLException {
+ LogicalConnectionImpl lc = new LogicalConnectionImpl( null,
ConnectionReleaseMode.AFTER_TRANSACTION, services );
+ BatchBuilder batchBuilder = new BatchBuilder( -1 );
+
+ Batch batch = batchBuilder.buildBatch( this, lc );
+ BatchCounter counter = new BatchCounter();
+ batch.addObserver( counter );
+ PreparedStatement ps = batch.getBatchStatement( "insert into SANDBOX_JDBC_TST( ID,
NAME ) values ( ?, ? )", false );
+ ps.setLong( 1, 1 );
+ ps.setString( 2, "name" );
+ batch.addToBatch( Expectations.BASIC );
+ assertEquals( 1, getRowCount() );
+ assertTrue( lc.getJdbcContainer().hasRegisteredResources() );
+ assertEquals( 0, counter.explicitBatchCount );
+ assertEquals( 1, counter.implicitBatchCount );
+ batch.execute();
+ assertEquals( 1, getRowCount() );
+ assertFalse( lc.getJdbcContainer().hasRegisteredResources() );
+ assertEquals( 1, counter.explicitBatchCount );
+ assertEquals( 1, counter.implicitBatchCount );
+ lc.close();
+ }
+}
Copied:
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/TestingServiceImpl.java
(from rev 13928,
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/proxy/TestingServiceImpl.java)
===================================================================
---
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/TestingServiceImpl.java
(rev 0)
+++
sandbox/trunk/jdbc-proxy/src/test/java/org/hibernate/jdbc/batch/TestingServiceImpl.java 2007-08-17
04:04:34 UTC (rev 13931)
@@ -0,0 +1,81 @@
+/*
+ * 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.batch;
+
+import java.sql.SQLException;
+
+import org.hibernate.cfg.Settings;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.exception.SQLStateConverter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.jdbc.ConnectionProviderBuilder;
+import org.hibernate.jdbc.JDBCContainer;
+import org.hibernate.jdbc.JDBCContainerBuilder;
+import org.hibernate.jdbc.JDBCServices;
+import org.hibernate.jdbc.proxy.ProxyJDBCContainer;
+import org.hibernate.jdbc.util.ExceptionHelper;
+import org.hibernate.jdbc.util.SQLStatementLogger;
+
+/**
+ * TestingServiceImpl implementation
+ *
+ * @author Steve Ebersole
+ */
+public class TestingServiceImpl implements JDBCServices {
+ private ConnectionProvider connectionProvider;
+ private SQLStatementLogger sqlStatementLogger;
+ private JDBCContainerBuilder jdbcContainerBuilder;
+ private ExceptionHelper exceptionHelper;
+
+ 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;
+ }
+ }
+ )
+ );
+ jdbcContainerBuilder = new JDBCContainerBuilder() {
+ public JDBCContainer buildJdbcContainer() {
+ return new ProxyJDBCContainer( exceptionHelper );
+ }
+ };
+ }
+
+ public void release() {
+ connectionProvider.close();
+ }
+
+ public ConnectionProvider getConnectionProvider() {
+ return connectionProvider;
+ }
+
+ public JDBCContainerBuilder getJdbcContainerBuilder() {
+ return jdbcContainerBuilder;
+ }
+
+ public SQLStatementLogger getSqlStatementLogger() {
+ return sqlStatementLogger;
+ }
+
+ public ExceptionHelper getExceptionHelper() {
+ return exceptionHelper;
+ }
+}
\ No newline at end of file