You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/02/08 13:41:55 UTC

cayenne git commit: PkGenerators cleanup

Repository: cayenne
Updated Branches:
  refs/heads/master b2957a69d -> 27fb5716a


PkGenerators cleanup


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/27fb5716
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/27fb5716
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/27fb5716

Branch: refs/heads/master
Commit: 27fb5716a0bd8b690591bc13096d2da6a8873e43
Parents: b2957a6
Author: Nikita Timofeev <st...@gmail.com>
Authored: Wed Feb 8 16:41:46 2017 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Wed Feb 8 16:41:46 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/dba/JdbcPkGenerator.java |  51 +++----
 .../apache/cayenne/dba/db2/DB2PkGenerator.java  | 141 ++-----------------
 .../cayenne/dba/derby/DerbyPkGenerator.java     |  12 +-
 .../apache/cayenne/dba/h2/H2PkGenerator.java    |  64 +--------
 .../cayenne/dba/ingres/IngresPkGenerator.java   |  64 +--------
 .../cayenne/dba/mysql/MySQLPkGenerator.java     |  79 ++++-------
 .../cayenne/dba/oracle/OraclePkGenerator.java   | 117 +++++++--------
 .../dba/postgres/PostgresPkGenerator.java       |  73 +---------
 .../cayenne/dba/sybase/SybasePkGenerator.java   |  62 +++-----
 .../apache/cayenne/tx/CayenneTransaction.java   |  93 ++++++------
 10 files changed, 207 insertions(+), 549 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
index 0187bf8..553283b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/JdbcPkGenerator.java
@@ -116,11 +116,8 @@ public class JdbcPkGenerator implements PkGenerator {
 	}
 
 	protected String pkTableCreateString() {
-		StringBuilder buf = new StringBuilder();
-		buf.append("CREATE TABLE AUTO_PK_SUPPORT (").append("  TABLE_NAME CHAR(100) NOT NULL,")
-				.append("  NEXT_ID BIGINT NOT NULL,").append("  PRIMARY KEY(TABLE_NAME)").append(")");
-
-		return buf.toString();
+		return "CREATE TABLE AUTO_PK_SUPPORT " +
+				"(TABLE_NAME CHAR(100) NOT NULL, NEXT_ID BIGINT NOT NULL, PRIMARY KEY(TABLE_NAME))";
 	}
 
 	protected String pkDeleteString(List<DbEntity> dbEntities) {
@@ -139,23 +136,15 @@ public class JdbcPkGenerator implements PkGenerator {
 	}
 
 	protected String pkCreateString(String entName) {
-		StringBuilder buf = new StringBuilder();
-		buf.append("INSERT INTO AUTO_PK_SUPPORT").append(" (TABLE_NAME, NEXT_ID)").append(" VALUES ('").append(entName)
-				.append("', ").append(pkStartValue).append(")");
-		return buf.toString();
+		return "INSERT INTO AUTO_PK_SUPPORT (TABLE_NAME, NEXT_ID) VALUES ('" + entName + "', " + pkStartValue + ")";
 	}
 
 	protected String pkSelectString(String entName) {
-		StringBuilder buf = new StringBuilder();
-		buf.append("SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = '").append(entName).append('\'');
-		return buf.toString();
+		return "SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = '" + entName + '\'';
 	}
 
 	protected String pkUpdateString(String entName) {
-		StringBuilder buf = new StringBuilder();
-		buf.append("UPDATE AUTO_PK_SUPPORT").append(" SET NEXT_ID = NEXT_ID + ").append(pkCacheSize)
-				.append(" WHERE TABLE_NAME = '").append(entName).append('\'');
-		return buf.toString();
+		return "UPDATE AUTO_PK_SUPPORT SET NEXT_ID = NEXT_ID + " + pkCacheSize + " WHERE TABLE_NAME = '" + entName + '\'';
 	}
 
 	protected String dropAutoPkString() {
@@ -167,10 +156,9 @@ public class JdbcPkGenerator implements PkGenerator {
 	 */
 	protected boolean autoPkTableExists(DataNode node) throws SQLException {
 
-		try (Connection con = node.getDataSource().getConnection();) {
+		try (Connection con = node.getDataSource().getConnection()) {
 			DatabaseMetaData md = con.getMetaData();
-
-			try (ResultSet tables = md.getTables(null, null, "AUTO_PK_SUPPORT", null);) {
+			try (ResultSet tables = md.getTables(null, null, "AUTO_PK_SUPPORT", null)) {
 				return tables.next();
 			}
 		}
@@ -186,8 +174,8 @@ public class JdbcPkGenerator implements PkGenerator {
 	public int runUpdate(DataNode node, String sql) throws SQLException {
 		adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
 
-		try (Connection con = node.getDataSource().getConnection();) {
-			try (Statement upd = con.createStatement();) {
+		try (Connection con = node.getDataSource().getConnection()) {
+			try (Statement upd = con.createStatement()) {
 				return upd.executeUpdate(sql);
 			}
 		}
@@ -205,7 +193,7 @@ public class JdbcPkGenerator implements PkGenerator {
 	 */
 	public Object generatePk(DataNode node, DbAttribute pk) throws Exception {
 
-		DbEntity entity = (DbEntity) pk.getEntity();
+		DbEntity entity = pk.getEntity();
 
 		switch (pk.getType()) {
 		case Types.BINARY:
@@ -215,10 +203,11 @@ public class JdbcPkGenerator implements PkGenerator {
 
 		DbKeyGenerator pkGenerator = entity.getPrimaryKeyGenerator();
 		long cacheSize;
-		if (pkGenerator != null && pkGenerator.getKeyCacheSize() != null)
-			cacheSize = pkGenerator.getKeyCacheSize().intValue();
-		else
+		if (pkGenerator != null && pkGenerator.getKeyCacheSize() != null) {
+			cacheSize = pkGenerator.getKeyCacheSize();
+		} else {
 			cacheSize = pkCacheSize;
+		}
 
 		Long value;
 
@@ -230,7 +219,7 @@ public class JdbcPkGenerator implements PkGenerator {
 
 			if (pks == null) {
 				// created exhausted LongPkRange
-				pks = new ConcurrentLinkedQueue<Long>();
+				pks = new ConcurrentLinkedQueue<>();
 				Queue<Long> previousPks = pkCache.putIfAbsent(entity.getName(), pks);
 				if (previousPks != null) {
 					pks = previousPks;
@@ -249,8 +238,7 @@ public class JdbcPkGenerator implements PkGenerator {
 		if (pk.getType() == Types.BIGINT) {
 			return value;
 		} else {
-			// leaving it up to the user to ensure that PK does not exceed max
-			// int...
+			// leaving it up to the user to ensure that PK does not exceed max int...
 			return value.intValue();
 		}
 	}
@@ -268,7 +256,7 @@ public class JdbcPkGenerator implements PkGenerator {
 	 * @since 3.0
 	 */
 	protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
-		String select = "SELECT #result('NEXT_ID' 'long' 'NEXT_ID') " + "FROM AUTO_PK_SUPPORT "
+		String select = "SELECT #result('NEXT_ID' 'long' 'NEXT_ID') FROM AUTO_PK_SUPPORT "
 				+ "WHERE TABLE_NAME = '" + entity.getName() + '\'';
 
 		// run queries via DataNode to utilize its transactional behavior
@@ -324,7 +312,7 @@ public class JdbcPkGenerator implements PkGenerator {
 	final class PkRetrieveProcessor implements OperationObserver {
 
 		Number id;
-		String entityName;
+		final String entityName;
 
 		PkRetrieveProcessor(String entityName) {
 			this.entityName = entityName;
@@ -343,7 +331,6 @@ public class JdbcPkGenerator implements PkGenerator {
 		}
 
 		public void nextRows(Query query, List<?> dataRows) {
-
 			// process selected object, issue an update query
 			if (dataRows == null || dataRows.size() == 0) {
 				throw new CayenneRuntimeException("Error generating PK : entity not supported: " + entityName);
@@ -375,12 +362,10 @@ public class JdbcPkGenerator implements PkGenerator {
 		}
 
 		public void nextQueryException(Query query, Exception ex) {
-
 			throw new CayenneRuntimeException("Error generating PK for entity '" + entityName + "'.", ex);
 		}
 
 		public void nextGlobalException(Exception ex) {
-
 			throw new CayenneRuntimeException("Error generating PK for entity: " + entityName, ex);
 		}
 	}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2PkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2PkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2PkGenerator.java
index 188a4a2..9f5e3da 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2PkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/db2/DB2PkGenerator.java
@@ -18,26 +18,14 @@
  ****************************************************************/
 package org.apache.cayenne.dba.db2;
 
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.dba.JdbcAdapter;
-import org.apache.cayenne.dba.JdbcPkGenerator;
-import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.dba.oracle.OraclePkGenerator;
 import org.apache.cayenne.map.DbEntity;
 
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * A sequence-based PK generator used by {@link DB2Adapter}.
  */
-public class DB2PkGenerator extends JdbcPkGenerator {
+public class DB2PkGenerator extends OraclePkGenerator {
 
 	DB2PkGenerator(JdbcAdapter adapter) {
 		super(adapter);
@@ -45,135 +33,34 @@ public class DB2PkGenerator extends JdbcPkGenerator {
 
 	private static final String _SEQUENCE_PREFIX = "S_";
 
-	/**
-	 * @since 3.0
-	 */
 	@Override
-	protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
-
-		String pkGeneratingSequenceName = sequenceName(entity);
-		try (Connection con = node.getDataSource().getConnection()) {
-			try (Statement st = con.createStatement()) {
-				String sql = "SELECT NEXTVAL FOR " + pkGeneratingSequenceName + " FROM SYSIBM.SYSDUMMY1";
-				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
-				try (ResultSet rs = st.executeQuery(sql)) {
-					if (!rs.next()) {
-						throw new CayenneRuntimeException("Error generating pk for DbEntity " + entity.getName());
-					}
-					return rs.getLong(1);
-				}
-			}
-		}
+	protected String sequenceName(DbEntity entity) {
+		return super.sequenceName(entity).toUpperCase();
 	}
 
 	@Override
-	public void createAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception {
-		Collection<String> sequences = getExistingSequences(node);
-		for (DbEntity entity : dbEntities) {
-			if (!sequences.contains(sequenceName(entity))) {
-				this.runUpdate(node, createSequenceString(entity));
-			}
-		}
+	protected String getSequencePrefix() {
+		return _SEQUENCE_PREFIX;
 	}
 
-	/**
-	 * Creates a list of CREATE SEQUENCE statements for the list of DbEntities.
-	 */
 	@Override
-	public List<String> createAutoPkStatements(List<DbEntity> dbEntities) {
-		List<String> list = new ArrayList<>(dbEntities.size());
-		for (DbEntity entity : dbEntities) {
-			list.add(createSequenceString(entity));
-		}
-		return list;
+	protected String selectNextValQuery(String pkGeneratingSequenceName) {
+		return "SELECT NEXTVAL FOR " + pkGeneratingSequenceName + " FROM SYSIBM.SYSDUMMY1";
 	}
 
-	/**
-	 * Drops PK sequences for all specified DbEntities.
-	 */
 	@Override
-	public void dropAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception {
-		Collection<String> sequences = getExistingSequences(node);
-
-		for (DbEntity ent : dbEntities) {
-			String name;
-			if (ent.getDataMap().isQuotingSQLIdentifiers()) {
-				DbEntity tempEnt = new DbEntity();
-				DataMap dm = new DataMap();
-				dm.setQuotingSQLIdentifiers(false);
-				tempEnt.setDataMap(dm);
-				tempEnt.setName(ent.getName());
-				name = sequenceName(tempEnt);
-			} else {
-				name = sequenceName(ent);
-			}
-			if (sequences.contains(name)) {
-				runUpdate(node, dropSequenceSql(ent));
-			}
-		}
+	protected String selectAllSequencesQuery() {
+		return "SELECT SEQNAME FROM SYSCAT.SEQUENCES WHERE SEQNAME LIKE '" + _SEQUENCE_PREFIX + "%'";
 	}
 
-	/**
-	 * Creates a list of DROP SEQUENCE statements for the list of DbEntities.
-	 */
 	@Override
-	public List<String> dropAutoPkStatements(List<DbEntity> dbEntities) {
-		List<String> list = new ArrayList<>(dbEntities.size());
-		for (DbEntity entity : dbEntities) {
-			list.add(dropSequenceSql(entity));
-		}
-		return list;
-	}
-
-	/**
-	 * Fetches a list of existing sequences that might match Cayenne generated
-	 * ones.
-	 */
-	protected List<String> getExistingSequences(DataNode node) throws SQLException {
-
-		// check existing sequences
-
-		try (Connection con = node.getDataSource().getConnection()) {
-			try (Statement sel = con.createStatement()) {
-				String sql = "SELECT SEQNAME FROM SYSCAT.SEQUENCES WHERE SEQNAME LIKE '" + _SEQUENCE_PREFIX + "%'";
-				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
-
-				try (ResultSet rs = sel.executeQuery(sql)) {
-					List<String> sequenceList = new ArrayList<>();
-					while (rs.next()) {
-						sequenceList.add(rs.getString(1).toUpperCase());
-					}
-					return sequenceList;
-				}
-			}
-		}
-	}
-
-	/**
-	 * Returns default sequence name for DbEntity.
-	 */
-	protected String sequenceName(DbEntity entity) {
-		String entName = entity.getName().toUpperCase();
-		String seqName = _SEQUENCE_PREFIX + entName;
-
-		return adapter.getQuotingStrategy().quotedIdentifier(entity, entity.getCatalog(), entity.getSchema(), seqName);
-	}
-
-	/**
-	 * Returns DROP SEQUENCE statement.
-	 */
-	protected String dropSequenceSql(DbEntity entity) {
+	protected String dropSequenceString(DbEntity entity) {
 		return "DROP SEQUENCE " + sequenceName(entity) + " RESTRICT ";
 	}
 
-	/**
-	 * Returns CREATE SEQUENCE statement for entity.
-	 */
+	@Override
 	protected String createSequenceString(DbEntity entity) {
-		StringBuilder buf = new StringBuilder();
-		buf.append("CREATE SEQUENCE ").append(sequenceName(entity)).append(" AS BIGINT START WITH ").append(pkStartValue)
-				.append(" INCREMENT BY ").append(getPkCacheSize()).append(" NO MAXVALUE ").append(" NO CYCLE ")
-				.append(" CACHE ").append(getPkCacheSize());
-		return buf.toString();
+		return "CREATE SEQUENCE " + sequenceName(entity) + " AS BIGINT START WITH " + pkStartValue +
+				" INCREMENT BY " + getPkCacheSize() + " NO MAXVALUE NO CYCLE CACHE " + getPkCacheSize();
 	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyPkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyPkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyPkGenerator.java
index 4ed7469..e2595ce 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyPkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyPkGenerator.java
@@ -43,7 +43,7 @@ public class DerbyPkGenerator extends JdbcPkGenerator {
 		super(adapter);
 	}
 
-	static final String SELECT_QUERY = "SELECT NEXT_ID FROM AUTO_PK_SUPPORT" + " WHERE TABLE_NAME = ? FOR UPDATE";
+	static final String SELECT_QUERY = "SELECT NEXT_ID FROM AUTO_PK_SUPPORT WHERE TABLE_NAME = ? FOR UPDATE";
 
 	/**
 	 * @since 3.0
@@ -56,13 +56,11 @@ public class DerbyPkGenerator extends JdbcPkGenerator {
 			logger.logQuery(SELECT_QUERY, Collections.singletonList(entity.getName()));
 		}
 
-		try (Connection c = node.getDataSource().getConnection();) {
-
-			try (PreparedStatement select = c.prepareStatement(SELECT_QUERY, ResultSet.TYPE_FORWARD_ONLY,
-					ResultSet.CONCUR_UPDATABLE);) {
+		try (Connection c = node.getDataSource().getConnection()) {
+			try (PreparedStatement select =
+						 c.prepareStatement(SELECT_QUERY, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
 				select.setString(1, entity.getName());
-
-				try (ResultSet rs = select.executeQuery();) {
+				try (ResultSet rs = select.executeQuery()) {
 					if (!rs.next()) {
 						throw new CayenneException("PK lookup failed for table: " + entity.getName());
 					}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2PkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2PkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2PkGenerator.java
index 3faf0e3..9e2e4d3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2PkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/h2/H2PkGenerator.java
@@ -19,20 +19,9 @@
 
 package org.apache.cayenne.dba.h2;
 
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.dba.JdbcAdapter;
 import org.apache.cayenne.dba.oracle.OraclePkGenerator;
 import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbKeyGenerator;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 
 /**
  * Default PK generator for H2 that uses sequences for PK generation.
@@ -52,57 +41,12 @@ public class H2PkGenerator extends OraclePkGenerator {
 	}
 
 	@Override
-	protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
-
-		DbKeyGenerator pkGenerator = entity.getPrimaryKeyGenerator();
-		String pkGeneratingSequenceName;
-		if (pkGenerator != null && DbKeyGenerator.ORACLE_TYPE.equals(pkGenerator.getGeneratorType())
-				&& pkGenerator.getGeneratorName() != null) {
-			pkGeneratingSequenceName = pkGenerator.getGeneratorName();
-		} else {
-			pkGeneratingSequenceName = sequenceName(entity);
-		}
-
-		try (Connection con = node.getDataSource().getConnection();) {
-
-			try (Statement st = con.createStatement();) {
-				String sql = "SELECT NEXT VALUE FOR " + pkGeneratingSequenceName;
-				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
-
-				try (ResultSet rs = st.executeQuery(sql);) {
-					// Object pk = null;
-					if (!rs.next()) {
-						throw new CayenneRuntimeException("Error generating pk for DbEntity " + entity.getName());
-					}
-					return rs.getLong(1);
-				}
-			}
-		}
+	protected String selectNextValQuery(String sequenceName) {
+		return "SELECT NEXT VALUE FOR " + sequenceName;
 	}
 
-	/**
-	 * Fetches a list of existing sequences that might match Cayenne generated
-	 * ones.
-	 */
 	@Override
-	protected List<String> getExistingSequences(DataNode node) throws SQLException {
-
-		// check existing sequences
-
-		try (Connection con = node.getDataSource().getConnection();) {
-
-			try (Statement sel = con.createStatement();) {
-				String sql = "SELECT LOWER(sequence_name) FROM Information_Schema.Sequences";
-				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
-
-				try (ResultSet rs = sel.executeQuery(sql);) {
-					List<String> sequenceList = new ArrayList<>();
-					while (rs.next()) {
-						sequenceList.add(rs.getString(1));
-					}
-					return sequenceList;
-				}
-			}
-		}
+	protected String selectAllSequencesQuery() {
+		return "SELECT LOWER(sequence_name) FROM Information_Schema.Sequences";
 	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresPkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresPkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresPkGenerator.java
index 0950e90..59a1183 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresPkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/ingres/IngresPkGenerator.java
@@ -19,20 +19,8 @@
 
 package org.apache.cayenne.dba.ingres;
 
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.dba.JdbcAdapter;
 import org.apache.cayenne.dba.oracle.OraclePkGenerator;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbKeyGenerator;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 
 /**
  * Ingres-specific sequence based PK generator.
@@ -46,56 +34,12 @@ public class IngresPkGenerator extends OraclePkGenerator {
 	}
 
 	@Override
-	protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
-
-		DbKeyGenerator pkGenerator = entity.getPrimaryKeyGenerator();
-		String pkGeneratingSequenceName;
-		if (pkGenerator != null && DbKeyGenerator.ORACLE_TYPE.equals(pkGenerator.getGeneratorType())
-				&& pkGenerator.getGeneratorName() != null) {
-			pkGeneratingSequenceName = pkGenerator.getGeneratorName();
-		} else {
-			pkGeneratingSequenceName = sequenceName(entity);
-		}
-
-		try (Connection con = node.getDataSource().getConnection();) {
-
-			try (Statement st = con.createStatement();) {
-				String sql = "SELECT " + pkGeneratingSequenceName + ".nextval";
-				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
-
-				try (ResultSet rs = st.executeQuery(sql);) {
-					// Object pk = null;
-					if (!rs.next()) {
-						throw new CayenneRuntimeException("Error generating pk for DbEntity " + entity.getName());
-					}
-					return rs.getLong(1);
-				}
-			}
-		}
+	protected String selectNextValQuery(String sequenceName) {
+		return "SELECT " + sequenceName + ".nextval";
 	}
 
 	@Override
-	protected List<String> getExistingSequences(DataNode node) throws SQLException {
-
-		// check existing sequences
-
-		try (Connection connection = node.getDataSource().getConnection();) {
-
-			try (Statement select = connection.createStatement();) {
-				String sql = "select seq_name from iisequences where seq_owner != 'DBA'";
-				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
-
-				try (ResultSet rs = select.executeQuery(sql);) {
-					List<String> sequenceList = new ArrayList<>();
-					while (rs.next()) {
-						String name = rs.getString(1);
-						if (name != null) {
-							sequenceList.add(name.trim());
-						}
-					}
-					return sequenceList;
-				}
-			}
-		}
+	protected String selectAllSequencesQuery() {
+		return "SELECT seq_name FROM iisequences WHERE seq_owner != 'DBA'";
 	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java
index 180a4c2..9e30749 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLPkGenerator.java
@@ -38,11 +38,6 @@ public class MySQLPkGenerator extends JdbcPkGenerator {
 		super(adapter);
 	}
 
-	@Override
-	protected String dropAutoPkString() {
-		return "DROP TABLE IF EXISTS AUTO_PK_SUPPORT";
-	}
-
 	/**
 	 * Overrides superclass's implementation to perform locking of the primary
 	 * key lookup table.
@@ -58,50 +53,39 @@ public class MySQLPkGenerator extends JdbcPkGenerator {
 
 		// chained SQL exception
 		SQLException exception = null;
-		long pk = -1l;
+		long pk = -1L;
 
-		try (Connection con = node.getDataSource().getConnection();) {
+		try (Connection con = node.getDataSource().getConnection()) {
 
 			if (con.getAutoCommit()) {
 				con.setAutoCommit(false);
 			}
 
-			Statement st = con.createStatement();
-
-			try {
-				pk = getLongPrimaryKey(st, entity.getName());
-				con.commit();
-			} catch (SQLException pkEx) {
-
+			try(Statement st = con.createStatement()) {
 				try {
-					con.rollback();
-				} catch (SQLException e) {
-
-				}
+					pk = getLongPrimaryKey(st, entity.getName());
+					con.commit();
+				} catch (SQLException pkEx) {
+					try {
+						con.rollback();
+					} catch (SQLException ignored) {
+					}
 
-				exception = processSQLException(pkEx, exception);
-			} finally {
-				// UNLOCK!
-				// THIS MUST BE EXECUTED NO MATTER WHAT, OR WE WILL LOCK THE
-				// PRIMARY KEY
-				// TABLE!!
-				try {
-					String unlockString = "UNLOCK TABLES";
-					adapter.getJdbcEventLogger().logQuery(unlockString, Collections.EMPTY_LIST);
-					st.execute(unlockString);
-				} catch (SQLException unlockEx) {
-					exception = processSQLException(unlockEx, exception);
+					exception = processSQLException(pkEx, null);
 				} finally {
-					// close statement
+					// UNLOCK!
+					// THIS MUST BE EXECUTED NO MATTER WHAT, OR WE WILL LOCK THE PRIMARY KEY TABLE!!
 					try {
-						st.close();
-					} catch (SQLException stClosingEx) {
-						// ignoring...
+						String unlockString = "UNLOCK TABLES";
+						adapter.getJdbcEventLogger().logQuery(unlockString, Collections.EMPTY_LIST);
+						st.execute(unlockString);
+					} catch (SQLException unlockEx) {
+						exception = processSQLException(unlockEx, exception);
 					}
 				}
 			}
 		} catch (SQLException otherEx) {
-			exception = processSQLException(otherEx, exception);
+			exception = processSQLException(otherEx, null);
 		}
 
 		// check errors
@@ -127,12 +111,14 @@ public class MySQLPkGenerator extends JdbcPkGenerator {
 	}
 
 	@Override
-	protected String pkTableCreateString() {
-		StringBuilder buf = new StringBuilder();
-		buf.append("CREATE TABLE IF NOT EXISTS AUTO_PK_SUPPORT (").append("  TABLE_NAME CHAR(100) NOT NULL,")
-				.append("  NEXT_ID BIGINT NOT NULL, UNIQUE (TABLE_NAME)").append(")");
+	protected String dropAutoPkString() {
+		return "DROP TABLE IF EXISTS AUTO_PK_SUPPORT";
+	}
 
-		return buf.toString();
+	@Override
+	protected String pkTableCreateString() {
+		return "CREATE TABLE IF NOT EXISTS AUTO_PK_SUPPORT " +
+				"(TABLE_NAME CHAR(100) NOT NULL, NEXT_ID BIGINT NOT NULL, UNIQUE (TABLE_NAME))";
 	}
 
 	/**
@@ -145,27 +131,18 @@ public class MySQLPkGenerator extends JdbcPkGenerator {
 		statement.execute(lockString);
 
 		// select
-
 		String selectString = super.pkSelectString(entityName);
 		adapter.getJdbcEventLogger().logQuery(selectString, Collections.EMPTY_LIST);
-		ResultSet rs = statement.executeQuery(selectString);
-		long pk = -1;
-		try {
+		long pk;
+		try(ResultSet rs = statement.executeQuery(selectString)) {
 			if (!rs.next()) {
 				throw new SQLException("No rows for '" + entityName + "'");
 			}
 
 			pk = rs.getLong(1);
-
 			if (rs.next()) {
 				throw new SQLException("More than one row for '" + entityName + "'");
 			}
-		} finally {
-			try {
-				rs.close();
-			} catch (Exception ex) {
-				// ignoring...
-			}
 		}
 
 		// update

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OraclePkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OraclePkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OraclePkGenerator.java
index 8cc9c7b..e059a74 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OraclePkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/oracle/OraclePkGenerator.java
@@ -33,7 +33,6 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -61,71 +60,70 @@ public class OraclePkGenerator extends JdbcPkGenerator {
 	private static final String _SEQUENCE_PREFIX = "pk_";
 
 	@Override
-	public void createAutoPk(DataNode node, List dbEntities) throws Exception {
-		List sequences = getExistingSequences(node);
-
+	public void createAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception {
+		List<String> sequences = getExistingSequences(node);
 		// create needed sequences
-		Iterator it = dbEntities.iterator();
-		while (it.hasNext()) {
-			DbEntity ent = (DbEntity) it.next();
-			if (!sequences.contains(sequenceName(ent))) {
-				runUpdate(node, createSequenceString(ent));
+		for (DbEntity dbEntity : dbEntities) {
+			if (!sequences.contains(sequenceName(dbEntity))) {
+				runUpdate(node, createSequenceString(dbEntity));
 			}
 		}
 	}
 
+	/**
+	 * Creates a list of CREATE SEQUENCE statements for the list of DbEntities.
+	 */
 	@Override
-	public List createAutoPkStatements(List dbEntities) {
-		List<String> list = new ArrayList<>();
-		Iterator it = dbEntities.iterator();
-		while (it.hasNext()) {
-			DbEntity ent = (DbEntity) it.next();
-			list.add(createSequenceString(ent));
+	public List<String> createAutoPkStatements(List<DbEntity> dbEntities) {
+		List<String> list = new ArrayList<>(dbEntities.size());
+		for (DbEntity dbEntity : dbEntities) {
+			list.add(createSequenceString(dbEntity));
 		}
 
 		return list;
 	}
 
+	/**
+	 * Drops PK sequences for all specified DbEntities.
+	 */
 	@Override
-	public void dropAutoPk(DataNode node, List dbEntities) throws Exception {
-		List sequences = getExistingSequences(node);
+	public void dropAutoPk(DataNode node, List<DbEntity> dbEntities) throws Exception {
+		List<String> sequences = getExistingSequences(node);
 
 		// drop obsolete sequences
-		Iterator it = dbEntities.iterator();
-		while (it.hasNext()) {
-			DbEntity ent = (DbEntity) it.next();
+		for (DbEntity dbEntity : dbEntities) {
 			String name;
-			if (ent.getDataMap().isQuotingSQLIdentifiers()) {
+			if (dbEntity.getDataMap().isQuotingSQLIdentifiers()) {
 				DbEntity tempEnt = new DbEntity();
 				DataMap dm = new DataMap();
 				dm.setQuotingSQLIdentifiers(false);
 				tempEnt.setDataMap(dm);
-				tempEnt.setName(ent.getName());
+				tempEnt.setName(dbEntity.getName());
 				name = stripSchemaName(sequenceName(tempEnt));
 			} else {
-				name = stripSchemaName(sequenceName(ent));
+				name = stripSchemaName(sequenceName(dbEntity));
 			}
 			if (sequences.contains(name)) {
-				runUpdate(node, dropSequenceString(ent));
+				runUpdate(node, dropSequenceString(dbEntity));
 			}
 		}
 	}
 
+	/**
+	 * Creates a list of DROP SEQUENCE statements for the list of DbEntities.
+	 */
 	@Override
-	public List dropAutoPkStatements(List dbEntities) {
-		List<String> list = new ArrayList<>();
-		Iterator it = dbEntities.iterator();
-		while (it.hasNext()) {
-			DbEntity ent = (DbEntity) it.next();
-			list.add(dropSequenceString(ent));
+	public List<String> dropAutoPkStatements(List<DbEntity> dbEntities) {
+		List<String> list = new ArrayList<>(dbEntities.size());
+		for (DbEntity dbEntity : dbEntities) {
+			list.add(dropSequenceString(dbEntity));
 		}
 
 		return list;
 	}
 
 	protected String createSequenceString(DbEntity ent) {
-		return "CREATE SEQUENCE " + sequenceName(ent) + " START WITH " + pkStartValue + " INCREMENT BY "
-				+ pkCacheSize(ent);
+		return "CREATE SEQUENCE " + sequenceName(ent) + " START WITH " + pkStartValue + " INCREMENT BY " + pkCacheSize(ent);
 	}
 
 	/**
@@ -133,10 +131,17 @@ public class OraclePkGenerator extends JdbcPkGenerator {
 	 * automatic primary key generation process for a specific DbEntity.
 	 */
 	protected String dropSequenceString(DbEntity ent) {
-
 		return "DROP SEQUENCE " + sequenceName(ent);
 	}
 
+	protected String selectNextValQuery(String pkGeneratingSequenceName) {
+		return "SELECT " + pkGeneratingSequenceName + ".nextval FROM DUAL";
+	}
+
+	protected String selectAllSequencesQuery() {
+		return "SELECT LOWER(SEQUENCE_NAME) FROM ALL_SEQUENCES";
+	}
+
 	/**
 	 * Generates primary key by calling Oracle sequence corresponding to the
 	 * <code>dbEntity</code>. Executed SQL looks like this:
@@ -159,14 +164,12 @@ public class OraclePkGenerator extends JdbcPkGenerator {
 			pkGeneratingSequenceName = sequenceName(entity);
 		}
 
-		try (Connection con = node.getDataSource().getConnection();) {
-
-			try (Statement st = con.createStatement();) {
-				String sql = "SELECT " + pkGeneratingSequenceName + ".nextval FROM DUAL";
+		try (Connection con = node.getDataSource().getConnection()) {
+			try (Statement st = con.createStatement()) {
+				String sql = selectNextValQuery(pkGeneratingSequenceName);
 				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
 
-				try (ResultSet rs = st.executeQuery(sql);) {
-					// Object pk = null;
+				try (ResultSet rs = st.executeQuery(sql)) {
 					if (!rs.next()) {
 						throw new CayenneRuntimeException("Error generating pk for DbEntity " + entity.getName());
 					}
@@ -183,13 +186,15 @@ public class OraclePkGenerator extends JdbcPkGenerator {
 				&& keyGenerator.getGeneratorName() != null) {
 
 			Integer size = keyGenerator.getKeyCacheSize();
-			return (size != null && size.intValue() >= 1) ? size.intValue() : super.getPkCacheSize();
+			return (size != null && size >= 1) ? size : super.getPkCacheSize();
 		} else {
 			return super.getPkCacheSize();
 		}
 	}
 
-	/** Returns expected primary key sequence name for a DbEntity. */
+	/**
+	 * Returns expected primary key sequence name for a DbEntity.
+	 */
 	protected String sequenceName(DbEntity entity) {
 
 		// use custom generator if possible
@@ -199,15 +204,16 @@ public class OraclePkGenerator extends JdbcPkGenerator {
 
 			return keyGenerator.getGeneratorName().toLowerCase();
 		} else {
-			String entName = entity.getName();
-			String seqName = _SEQUENCE_PREFIX + entName.toLowerCase();
-
-			return adapter.getQuotingStrategy().quotedIdentifier(entity, entity.getCatalog(), entity.getSchema(),
-					seqName);
+			String seqName = getSequencePrefix() + entity.getName().toLowerCase();
+			return adapter.getQuotingStrategy().quotedIdentifier(entity, entity.getCatalog(), entity.getSchema(), seqName);
 		}
 	}
 
-	protected String stripSchemaName(String sequenceName) {
+	protected String getSequencePrefix() {
+		return _SEQUENCE_PREFIX;
+	}
+
+	private String stripSchemaName(String sequenceName) {
 		int ind = sequenceName.indexOf('.');
 		return ind >= 0 ? sequenceName.substring(ind + 1) : sequenceName;
 	}
@@ -216,20 +222,21 @@ public class OraclePkGenerator extends JdbcPkGenerator {
 	 * Fetches a list of existing sequences that might match Cayenne generated
 	 * ones.
 	 */
-	protected List getExistingSequences(DataNode node) throws SQLException {
+	protected List<String> getExistingSequences(DataNode node) throws SQLException {
 
 		// check existing sequences
-
-		try (Connection con = node.getDataSource().getConnection();) {
-
-			try (Statement sel = con.createStatement();) {
-				String sql = "SELECT LOWER(SEQUENCE_NAME) FROM ALL_SEQUENCES";
+		try (Connection con = node.getDataSource().getConnection()) {
+			try (Statement sel = con.createStatement()) {
+				String sql = selectAllSequencesQuery();
 				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
 
-				try (ResultSet rs = sel.executeQuery(sql);) {
+				try (ResultSet rs = sel.executeQuery(sql)) {
 					List<String> sequenceList = new ArrayList<>();
 					while (rs.next()) {
-						sequenceList.add(rs.getString(1));
+						String name = rs.getString(1);
+						if (name != null) {
+							sequenceList.add(name.trim());
+						}
 					}
 					return sequenceList;
 				}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresPkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresPkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresPkGenerator.java
index 877fc33..4b5bb1e 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresPkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/postgres/PostgresPkGenerator.java
@@ -19,20 +19,9 @@
 
 package org.apache.cayenne.dba.postgres;
 
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.dba.JdbcAdapter;
 import org.apache.cayenne.dba.oracle.OraclePkGenerator;
 import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.map.DbKeyGenerator;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
 
 /**
  * Default PK generator for PostgreSQL that uses sequences for PK generation.
@@ -45,69 +34,19 @@ public class PostgresPkGenerator extends OraclePkGenerator {
 
 	@Override
 	protected String createSequenceString(DbEntity ent) {
-		// note that PostgreSQL 7.4 and newer supports INCREMENT BY and START
-		// WITH
+		// note that PostgreSQL 7.4 and newer supports INCREMENT BY and START WITH
 		// however 7.3 doesn't like BY and WITH, so using older more neutral
-		// syntax
-		// that works with all tested versions.
+		// syntax that works with all tested versions.
 		return "CREATE SEQUENCE " + sequenceName(ent) + " INCREMENT " + pkCacheSize(ent) + " START " + pkStartValue;
 	}
 
-	/**
-	 * @since 3.0
-	 */
 	@Override
-	protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
-
-		DbKeyGenerator pkGenerator = entity.getPrimaryKeyGenerator();
-		String pkGeneratingSequenceName;
-		if (pkGenerator != null && DbKeyGenerator.ORACLE_TYPE.equals(pkGenerator.getGeneratorType())
-				&& pkGenerator.getGeneratorName() != null) {
-			pkGeneratingSequenceName = pkGenerator.getGeneratorName();
-		} else {
-			pkGeneratingSequenceName = sequenceName(entity);
-		}
-
-		try (Connection con = node.getDataSource().getConnection();) {
-
-			try (Statement st = con.createStatement();) {
-				String sql = "SELECT nextval('" + pkGeneratingSequenceName + "')";
-				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
-
-				try (ResultSet rs = st.executeQuery(sql);) {
-					// Object pk = null;
-					if (!rs.next()) {
-						throw new CayenneRuntimeException("Error generating pk for DbEntity " + entity.getName());
-					}
-					return rs.getLong(1);
-				}
-			}
-		}
+	protected String selectNextValQuery(String sequenceName) {
+		return "SELECT nextval('" + sequenceName + "')";
 	}
 
-	/**
-	 * Fetches a list of existing sequences that might match Cayenne generated
-	 * ones.
-	 */
 	@Override
-	protected List<String> getExistingSequences(DataNode node) throws SQLException {
-
-		// check existing sequences
-
-		try (Connection con = node.getDataSource().getConnection();) {
-
-			try (Statement sel = con.createStatement();) {
-				String sql = "SELECT relname FROM pg_class WHERE relkind='S'";
-				adapter.getJdbcEventLogger().logQuery(sql, Collections.EMPTY_LIST);
-
-				try (ResultSet rs = sel.executeQuery(sql);) {
-					List<String> sequenceList = new ArrayList<>();
-					while (rs.next()) {
-						sequenceList.add(rs.getString(1));
-					}
-					return sequenceList;
-				}
-			}
-		}
+	protected String selectAllSequencesQuery() {
+		return "SELECT relname FROM pg_class WHERE relkind='S'";
 	}
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java
index e08a099..9c24f1a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sybase/SybasePkGenerator.java
@@ -46,7 +46,7 @@ public class SybasePkGenerator extends JdbcPkGenerator {
 
 	@Override
 	protected String pkTableCreateString() {
-		return "CREATE TABLE AUTO_PK_SUPPORT (  TABLE_NAME CHAR(100) NOT NULL, NEXT_ID DECIMAL(19,0) NOT NULL, PRIMARY KEY(TABLE_NAME))";
+		return "CREATE TABLE AUTO_PK_SUPPORT (TABLE_NAME CHAR(100) NOT NULL, NEXT_ID DECIMAL(19,0) NOT NULL, PRIMARY KEY(TABLE_NAME))";
 	}
 
 	/**
@@ -149,47 +149,34 @@ public class SybasePkGenerator extends JdbcPkGenerator {
 	@Override
 	protected long longPkFromDatabase(DataNode node, DbEntity entity) throws Exception {
 		// handle CAY-588 - get connection that is separate from the connection
-		// in the
-		// current transaction.
+		// in the current transaction.
 
 		// TODO (andrus, 7/6/2006) Note that this will still work in a pool with
-		// a single
-		// connection, as PK generator is invoked early in the transaction,
-		// before the
-		// connection is grabbed for commit... So maybe promote this to other
-		// adapters in
-		// 3.0?
+		// a single connection, as PK generator is invoked early in the transaction,
+		// before the connection is grabbed for commit...
+		// So maybe promote this to other adapters in 3.0?
 
 		Transaction transaction = BaseTransaction.getThreadTransaction();
 		BaseTransaction.bindThreadTransaction(null);
 
-		try {
-
-			try (Connection connection = node.getDataSource().getConnection();) {
-
-				try (CallableStatement statement = connection.prepareCall("{call auto_pk_for_table(?, ?)}");) {
-					statement.setString(1, entity.getName());
-					statement.setInt(2, super.getPkCacheSize());
-
-					// can't use "executeQuery"
-					// per
-					// http://jtds.sourceforge.net/faq.html#expectingResultSet
-					statement.execute();
-					if (statement.getMoreResults()) {
-
-						try (ResultSet rs = statement.getResultSet();) {
-							if (rs.next()) {
-								return rs.getLong(1);
-							} else {
-								throw new CayenneRuntimeException("Error generating pk for DbEntity "
-										+ entity.getName());
-							}
+		try (Connection connection = node.getDataSource().getConnection()) {
+			try (CallableStatement statement = connection.prepareCall("{call auto_pk_for_table(?, ?)}")) {
+				statement.setString(1, entity.getName());
+				statement.setInt(2, super.getPkCacheSize());
+
+				// can't use "executeQuery" per http://jtds.sourceforge.net/faq.html#expectingResultSet
+				statement.execute();
+				if (statement.getMoreResults()) {
+					try (ResultSet rs = statement.getResultSet()) {
+						if (rs.next()) {
+							return rs.getLong(1);
+						} else {
+							throw new CayenneRuntimeException("Error generating pk for DbEntity " + entity.getName());
 						}
-
-					} else {
-						throw new CayenneRuntimeException("Error generating pk for DbEntity " + entity.getName()
-								+ ", no result set from stored procedure.");
 					}
+				} else {
+					throw new CayenneRuntimeException("Error generating pk for DbEntity " + entity.getName()
+							+ ", no result set from stored procedure.");
 				}
 			}
 		} finally {
@@ -198,11 +185,8 @@ public class SybasePkGenerator extends JdbcPkGenerator {
 	}
 
 	private String safePkTableDrop() {
-		StringBuilder buf = new StringBuilder();
-		buf.append("if exists (SELECT * FROM sysobjects WHERE name = 'AUTO_PK_SUPPORT')").append(" BEGIN ")
-				.append(" DROP TABLE AUTO_PK_SUPPORT").append(" END");
-
-		return buf.toString();
+		return "if exists (SELECT * FROM sysobjects WHERE name = 'AUTO_PK_SUPPORT') BEGIN " +
+				" DROP TABLE AUTO_PK_SUPPORT END";
 	}
 
 	private String unsafePkProcCreate() {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/27fb5716/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java b/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java
index f0ab5d8..dba12d9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/tx/CayenneTransaction.java
@@ -24,7 +24,6 @@ import org.apache.cayenne.log.JdbcEventLogger;
 
 import java.sql.Connection;
 import java.sql.SQLException;
-import java.util.Iterator;
 
 /**
  * Represents a Cayenne-managed local Transaction.
@@ -74,40 +73,36 @@ public class CayenneTransaction extends BaseTransaction {
     protected void processCommit() {
         status = BaseTransaction.STATUS_COMMITTING;
 
-        if (connections != null && connections.size() > 0) {
-            Throwable deferredException = null;
-            Iterator<?> it = connections.values().iterator();
-            while (it.hasNext()) {
-                Connection connection = (Connection) it.next();
-                try {
-
-                    if (deferredException == null) {
-                        connection.commit();
-                    } else {
-                        // we must do a partial rollback if only to cleanup
-                        // uncommitted
-                        // connections.
-                        connection.rollback();
-                    }
-
-                } catch (Throwable th) {
-                    // there is no such thing as "partial" rollback in real
-                    // transactions, so we can't set any meaningful status.
-                    // status = ?;
-                    setRollbackOnly();
-
-                    // stores last exception
-                    // TODO: chain exceptions...
-                    deferredException = th;
+        if (connections == null || connections.isEmpty()) {
+            return;
+        }
+
+        Throwable deferredException = null;
+        for (Connection connection : connections.values()) {
+            try {
+                if (deferredException == null) {
+                    connection.commit();
+                } else {
+                    // we must do a partial rollback if only to cleanup uncommitted connections.
+                    connection.rollback();
                 }
+            } catch (Throwable th) {
+                // there is no such thing as "partial" rollback in real
+                // transactions, so we can't set any meaningful status.
+                // status = ?;
+                setRollbackOnly();
+
+                // stores last exception
+                // TODO: chain exceptions...
+                deferredException = th;
             }
+        }
 
-            if (deferredException != null) {
-                logger.logRollbackTransaction("transaction rolledback.");
-                throw new CayenneRuntimeException(deferredException);
-            } else {
-                logger.logCommitTransaction("transaction committed.");
-            }
+        if (deferredException != null) {
+            logger.logRollbackTransaction("transaction rolledback.");
+            throw new CayenneRuntimeException(deferredException);
+        } else {
+            logger.logCommitTransaction("transaction committed.");
         }
     }
 
@@ -115,27 +110,25 @@ public class CayenneTransaction extends BaseTransaction {
     protected void processRollback() {
         status = BaseTransaction.STATUS_ROLLING_BACK;
 
-        if (connections != null && connections.size() > 0) {
-            Throwable deferredException = null;
-
-            Iterator<?> it = connections.values().iterator();
-            while (it.hasNext()) {
-                Connection connection = (Connection) it.next();
+        if (connections == null || connections.isEmpty()) {
+            return;
+        }
 
-                try {
-                    // continue with rollback even if an exception was thrown
-                    // before
-                    connection.rollback();
-                } catch (Throwable th) {
-                    // stores last exception
-                    // TODO: chain exceptions...
-                    deferredException = th;
-                }
+        Throwable deferredException = null;
+        for (Connection connection : connections.values()) {
+            try {
+                // continue with rollback even if an exception was thrown
+                // before
+                connection.rollback();
+            } catch (Throwable th) {
+                // stores last exception
+                // TODO: chain exceptions...
+                deferredException = th;
             }
+        }
 
-            if (deferredException != null) {
-                throw new CayenneRuntimeException(deferredException);
-            }
+        if (deferredException != null) {
+            throw new CayenneRuntimeException(deferredException);
         }
     }
 }