diff --git a/pom.xml b/pom.xml
index 28ae85a..39c4468 100644
--- a/pom.xml
+++ b/pom.xml
@@ -325,6 +325,13 @@
     </dependency>
 
     <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>1.8.4</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
       <groupId>com.h2database</groupId>
       <artifactId>h2</artifactId>
       <version>1.2.125</version>
diff --git a/src/test/java/com/google/gwtorm/jdbc/TestJdbcAccess.java b/src/test/java/com/google/gwtorm/jdbc/TestJdbcAccess.java
new file mode 100644
index 0000000..096a531
--- /dev/null
+++ b/src/test/java/com/google/gwtorm/jdbc/TestJdbcAccess.java
@@ -0,0 +1,485 @@
+// Copyright (C) 2011 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gwtorm.jdbc;
+
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import com.google.gwtorm.client.Key;
+import com.google.gwtorm.schema.sql.SqlDialect;
+import com.google.gwtorm.server.Access;
+import com.google.gwtorm.server.OrmConcurrencyException;
+import com.google.gwtorm.server.OrmException;
+import com.google.gwtorm.server.ResultSet;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.stubbing.OngoingStubbing;
+
+import java.sql.BatchUpdateException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+
+public class TestJdbcAccess {
+
+  private static final String INSERT = "insert";
+  private static final String UPDATE = "update";
+  private static final String DELETE = "delete";
+
+  private static final SqlDialect DIALECT = mock(SqlDialect.class,
+      CALLS_REAL_METHODS);
+
+  private static final Iterable<Data> NO_DATA = asList();
+  private static  Iterable<Data> ONE_ROW = asList(new Data(1));
+  private static  Iterable<Data> TWO_ROWS = asList(new Data(1), new Data(2));
+  private Connection conn;
+
+
+  private PreparedStatement stubStatementWithUpdateCounts(String command,
+      final int... updateCounts) throws SQLException {
+    PreparedStatement ps = mock(PreparedStatement.class);
+
+    // batching
+    doNothing().when(ps).addBatch();
+    when(ps.executeBatch()).thenReturn(updateCounts);
+
+    // non-batching
+    if (updateCounts != null && updateCounts.length > 0) {
+      OngoingStubbing<Integer> stubber = when(ps.executeUpdate());
+      for (int updateCount : updateCounts) {
+        stubber = stubber.thenReturn(updateCount);
+      }
+    }
+
+    when(conn.prepareStatement(command)).thenReturn(ps);
+    return ps;
+  }
+
+  private PreparedStatement stubStatementThrowExceptionOnExecute(
+      String command, SQLException exception) throws SQLException {
+    PreparedStatement ps = mock(PreparedStatement.class);
+    doNothing().when(ps).addBatch();
+    when(ps.executeBatch()).thenThrow(exception);
+    when(ps.executeUpdate()).thenThrow(exception);
+    when(conn.prepareStatement(command)).thenReturn(ps);
+    return ps;
+  }
+
+  private JdbcAccess<Data, Data.DataKey> createJdbcAccess(
+      final SqlDialect dialect) {
+    JdbcSchema schema = setupSchema(dialect);
+
+    JdbcAccess<Data, Data.DataKey> classUnderTest = new DataJdbcAccess(schema);
+    return classUnderTest;
+  }
+
+  private JdbcAccess<Data, Data.DataKey> createClassUnderTest() {
+    return createJdbcAccess(DIALECT);
+  }
+
+  private JdbcSchema setupSchema(final SqlDialect dialect) {
+    @SuppressWarnings("rawtypes")
+    Database db = mock(Database.class);
+    try {
+      when(db.getDialect()).thenReturn(dialect);
+
+      when(db.newConnection()).thenReturn(conn);
+
+      JdbcSchema schema = new Schema(db);
+      return schema;
+    } catch (OrmException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private static void assertNotUsed(PreparedStatement insert) {
+    verifyZeroInteractions(insert);
+  }
+
+  private static void assertUsedBatchingOnly(PreparedStatement statement)
+      throws SQLException {
+    verify(statement, atLeastOnce()).addBatch();
+    verify(statement).executeBatch();
+    verify(statement, never()).executeUpdate();
+  }
+
+  private static void assertExpectedIdsUsed(PreparedStatement statement,
+      int... ids) throws SQLException {
+
+    Set<Integer> notSet = new HashSet<Integer>(2);
+    notSet.add(1);
+    notSet.add(2);
+
+    for (int id : ids) {
+      verify(statement).setInt(1, id);
+      notSet.remove(Integer.valueOf(id));
+    }
+
+    for (Integer id : notSet) {
+      verify(statement, never()).setInt(1, id);
+    }
+  }
+
+  @Before
+  public void setup() {
+    conn = mock(Connection.class);
+  }
+
+  @Test
+  public void testInsertNothing() throws OrmException {
+    setup();
+    createClassUnderTest().insert(NO_DATA);
+  }
+
+  @Test
+  public void testInsertOne() throws OrmException, SQLException {
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT, 1);
+
+    createClassUnderTest().insert(ONE_ROW);
+
+    assertUsedBatchingOnly(insert);
+  }
+
+  @Test
+  public void testInsertOneDBException() throws OrmException, SQLException {
+    SQLException exception = new BatchUpdateException();
+    PreparedStatement insert =
+        stubStatementThrowExceptionOnExecute(INSERT, exception);
+    JdbcAccess<Data, Data.DataKey> classUnderTest = createClassUnderTest();
+    try {
+      classUnderTest.insert(ONE_ROW);
+      fail("missingException");
+    } catch (OrmException e) {
+      // expected
+      assertSame(e.getCause(), exception);
+    }
+
+    assertUsedBatchingOnly(insert);
+  }
+
+  @Test
+  public void testUpdateNothing() throws OrmException {
+    createClassUnderTest().update(NO_DATA);
+  }
+
+  @Test
+  public void testUpdateOne() throws OrmException, SQLException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE, 1);
+
+    createClassUnderTest().update(ONE_ROW);
+
+    assertUsedBatchingOnly(update);
+  }
+
+  @Test
+  public void testUpdateOneDBException() throws OrmException, SQLException {
+    SQLException exception = new BatchUpdateException();
+    PreparedStatement update =
+        stubStatementThrowExceptionOnExecute(UPDATE, exception);
+    JdbcAccess<Data, Data.DataKey> classUnderTest = createClassUnderTest();
+    try {
+      classUnderTest.update(ONE_ROW);
+      fail("missingException");
+    } catch (OrmException e) {
+      // expected
+      assertSame(e.getCause(), exception);
+    }
+
+    assertUsedBatchingOnly(update);
+  }
+
+  @Test
+  public void testUpdateOneConcurrentlyModifiedException() throws SQLException,
+      OrmException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE, 0);
+    JdbcAccess<Data, Data.DataKey> classUnderTest = createClassUnderTest();
+    try {
+      classUnderTest.update(ONE_ROW);
+      fail("missing OrmConcurrencyException");
+    } catch (OrmConcurrencyException e) {
+      // expected
+    }
+    assertUsedBatchingOnly(update);
+  }
+
+  @Test
+  public void testUpsertNothing() throws OrmException, SQLException {
+    createClassUnderTest().upsert(NO_DATA);
+  }
+
+  @Test
+  public void testUpsertOneExisting() throws OrmException, SQLException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE, 1);
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT);
+
+    createClassUnderTest().upsert(ONE_ROW);
+
+    assertUsedBatchingOnly(update);
+    assertNotUsed(insert);
+  }
+
+  @Test
+  public void testUpsertOneException() throws OrmException, SQLException {
+    SQLException exception = new BatchUpdateException();
+    PreparedStatement update =
+        stubStatementThrowExceptionOnExecute(UPDATE, exception);
+    JdbcAccess<Data, Data.DataKey> classUnderTest = createClassUnderTest();
+    try {
+      classUnderTest.upsert(ONE_ROW);
+      fail("missingException");
+    } catch (OrmException e) {
+      // expected
+      assertSame(e.getCause(), exception);
+    }
+
+    assertUsedBatchingOnly(update);
+  }
+
+  @Test
+  public void testUpsertOneNotExisting() throws OrmException, SQLException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE);
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT, 1);
+
+    createClassUnderTest().upsert(ONE_ROW);
+
+    assertUsedBatchingOnly(update);
+    assertUsedBatchingOnly(insert);
+    assertExpectedIdsUsed(insert, 1);
+  }
+
+  @Test
+  public void testUpsertTwoNotExistingZeroLengthArray() throws SQLException,
+      OrmException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE);
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT, 1, 1);
+
+    createClassUnderTest().upsert(TWO_ROWS);
+
+    assertUsedBatchingOnly(update);
+    assertUsedBatchingOnly(insert);
+    assertExpectedIdsUsed(insert, 1, 2);
+  }
+
+  @Test
+  public void testUpsertTwoNotExisting() throws SQLException, OrmException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE, 0, 0);
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT, 1, 1);
+
+    createClassUnderTest().upsert(TWO_ROWS);
+
+    assertUsedBatchingOnly(update);
+    assertUsedBatchingOnly(insert);
+    assertExpectedIdsUsed(insert, 1, 2);
+  }
+
+  @Test
+  public void testUpsertTwoBothExisting() throws SQLException, OrmException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE, 1, 1);
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT);
+
+    createClassUnderTest().upsert(TWO_ROWS);
+
+    assertUsedBatchingOnly(update);
+    assertNotUsed(insert);
+  }
+
+  @Test
+  public void testUpsertTwoFirstExisting() throws SQLException, OrmException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE, 1, 0);
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT, 1);
+
+    createClassUnderTest().upsert(TWO_ROWS);
+
+    assertUsedBatchingOnly(update);
+    assertUsedBatchingOnly(insert);
+    assertExpectedIdsUsed(insert, 2);
+  }
+
+  @Test
+  public void testUpsertTwoSecondExisting() throws SQLException, OrmException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE, 0, 1);
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT, 1);
+
+    createClassUnderTest().upsert(TWO_ROWS);
+
+    assertUsedBatchingOnly(update);
+    assertUsedBatchingOnly(insert);
+    assertExpectedIdsUsed(insert, 1);
+  }
+
+  @Test
+  public void testUpsertTwoUpdateCountsAreNull() throws SQLException,
+      OrmException {
+    PreparedStatement update = stubStatementWithUpdateCounts(UPDATE, null);
+    PreparedStatement insert = stubStatementWithUpdateCounts(INSERT, 1, 1);
+
+    createClassUnderTest().upsert(TWO_ROWS);
+
+    assertUsedBatchingOnly(update);
+    assertUsedBatchingOnly(insert);
+    assertExpectedIdsUsed(insert, 1, 2);
+  }
+
+  @Test
+  public void testDeleteOneExisting() throws SQLException, OrmException {
+    PreparedStatement delete = stubStatementWithUpdateCounts(DELETE, 1);
+
+    createClassUnderTest().delete(ONE_ROW);
+
+    assertUsedBatchingOnly(delete);
+  }
+
+  @Test
+  public void testDeleteOneNotExisting() throws SQLException, OrmException {
+    PreparedStatement delete = stubStatementWithUpdateCounts(DELETE, 0);
+    JdbcAccess<Data, Data.DataKey> classUnderTest = createClassUnderTest();
+    try {
+      classUnderTest.delete(ONE_ROW);
+      fail("missing OrmConcurrencyException");
+    } catch (OrmConcurrencyException e) {
+      // expected
+    }
+
+    assertUsedBatchingOnly(delete);
+  }
+
+  private class Schema extends JdbcSchema {
+
+    protected Schema(Database<?> d) throws OrmException {
+      super(d);
+    }
+
+    @Override
+    public Access<?, ?>[] allRelations() {
+      throw new UnsupportedOperationException();
+    }
+
+  }
+
+  private static class Data {
+
+    private final int id;
+
+    Data(int anId) {
+      id = anId;
+    }
+
+    private static class DataKey implements Key<Key<?>> {
+
+      @Override
+      public com.google.gwtorm.client.Key<?> getParentKey() {
+        throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public void fromString(String in) {
+        throw new UnsupportedOperationException();
+      }
+
+    }
+
+  }
+
+  private static class DataJdbcAccess extends JdbcAccess<Data, Data.DataKey> {
+
+    protected DataJdbcAccess(JdbcSchema s) {
+      super(s);
+    }
+
+    public String getRelationName() {
+      return "Data";
+    }
+
+    @Override
+    public com.google.gwtorm.jdbc.TestJdbcAccess.Data.DataKey primaryKey(
+        Data entity) {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Data get(com.google.gwtorm.jdbc.TestJdbcAccess.Data.DataKey key)
+        throws OrmException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected Data newEntityInstance() {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected String getInsertOneSql() {
+      return INSERT;
+    }
+
+    @Override
+    protected String getUpdateOneSql() {
+      return UPDATE;
+    }
+
+    @Override
+    protected String getDeleteOneSql() {
+      return DELETE;
+    }
+
+    @Override
+    protected void bindOneInsert(PreparedStatement ps, Data entity)
+        throws SQLException {
+      ps.setInt(1, entity.id);
+    }
+
+    @Override
+    protected void bindOneUpdate(PreparedStatement ps, Data entity)
+        throws SQLException {
+      ps.setInt(1, entity.id);
+    }
+
+    @Override
+    protected void bindOneDelete(PreparedStatement ps, Data entity)
+        throws SQLException {
+      ps.setInt(1, entity.id);
+    }
+
+    @Override
+    protected void bindOneFetch(java.sql.ResultSet rs, Data entity)
+        throws SQLException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getRelationID() {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ResultSet<Data> iterateAllEntities() throws OrmException {
+      throw new UnsupportedOperationException();
+    }
+
+  }
+}
