This is an automated email from the ASF dual-hosted git repository. johnthuss pushed a commit to branch genpkbatch in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 57332e865f5dabb9c7adef4bac9a61137f6828c4 Author: John Huss <johnth...@apache.org> AuthorDate: Mon Feb 17 09:27:06 2020 -0600 CAY-2650 Support using generated primary keys along with batch inserts Fixed unit tests for Derby and MSSQL --- .../apache/cayenne/access/jdbc/BatchAction.java | 27 ++++++++++++++-------- .../java/org/apache/cayenne/dba/DbAdapter.java | 7 ++++++ .../org/apache/cayenne/dba/derby/DerbyAdapter.java | 8 +++++++ .../cayenne/dba/sqlserver/SQLServerAdapter.java | 8 +++++++ .../access/jdbc/BatchActionGeneratedIT.java | 4 +++- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java index 3bcea41..e8ba334 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/jdbc/BatchAction.java @@ -86,12 +86,16 @@ public class BatchAction extends BaseSQLAction { public void performAction(Connection connection, OperationObserver observer) throws SQLException, Exception { BatchTranslator translator = createTranslator(); - boolean generatesKeys = hasGeneratedKeys(); - - if (runningAsBatch) { - runAsBatch(connection, translator, observer, generatesKeys); + + boolean isBatch = runningAsBatch && query.getRows().size() > 1; + if (isBatch && hasGeneratedKeys() && !supportsGeneratedKeys(isBatch)) { + isBatch = false; // turn off batch mode if we generate keys but can't do so in a batch + } + + if (isBatch) { + runAsBatch(connection, translator, observer, hasGeneratedKeys() && supportsGeneratedKeys(isBatch)); } else { - runAsIndividualQueries(connection, translator, observer, generatesKeys); + runAsIndividualQueries(connection, translator, observer, hasGeneratedKeys() && supportsGeneratedKeys(isBatch)); } } @@ -200,15 +204,18 @@ public class BatchAction extends BaseSQLAction { : connection.prepareStatement(queryStr); } + protected boolean supportsGeneratedKeys(boolean isBatch) { + // see if we are configured to support generated keys + boolean isSupported = isBatch + ? dataNode.getAdapter().supportsGeneratedKeysForBatchInserts() + : dataNode.getAdapter().supportsGeneratedKeys(); + return isSupported; + } + /** * Returns whether BatchQuery generates any keys. */ protected boolean hasGeneratedKeys() { - // see if we are configured to support generated keys - if (!dataNode.getAdapter().supportsGeneratedKeys()) { - return false; - } - // see if the query needs them if (query instanceof InsertBatchQuery) { diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java index caf61df..c657d6d 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/DbAdapter.java @@ -103,6 +103,13 @@ public interface DbAdapter { */ boolean supportsGeneratedKeys(); + /** + * @since 4.2 + */ + default boolean supportsGeneratedKeysForBatchInserts() { + return supportsGeneratedKeys(); + } + /** * Returns <code>true</code> if the target database supports batch updates. */ diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java index 14001b2..aaa4864 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/derby/DerbyAdapter.java @@ -88,6 +88,14 @@ public class DerbyAdapter extends JdbcAdapter { setSupportsBatchUpdates(true); } + /** + * Not supported, see: <a href="https://issues.apache.org/jira/browse/DERBY-3609">DERBY-3609</a> + */ + @Override + public boolean supportsGeneratedKeysForBatchInserts() { + return false; + } + @Override protected PkGenerator createPkGenerator() { return new DerbyPkGenerator(this); diff --git a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java index 0da1518..470444f 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/dba/sqlserver/SQLServerAdapter.java @@ -97,6 +97,14 @@ public class SQLServerAdapter extends SybaseAdapter { this.setSupportsBatchUpdates(true); } + /** + * Not supported, see: <a href="http://microsoft/mssql-jdbc#245">mssql-jdbc #245</a> + */ + @Override + public boolean supportsGeneratedKeysForBatchInserts() { + return false; + } + /** * @since 4.2 */ diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/jdbc/BatchActionGeneratedIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/jdbc/BatchActionGeneratedIT.java index d226553..166762c 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/jdbc/BatchActionGeneratedIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/jdbc/BatchActionGeneratedIT.java @@ -79,7 +79,9 @@ public class BatchActionGeneratedIT extends ServerCase { node.setEntityResolver(resolver); node.setRowReaderFactory(mock(RowReaderFactory.class)); - assertFalse(new BatchAction(batch1, node, false).hasGeneratedKeys()); + assertTrue(new BatchAction(batch1, node, false).hasGeneratedKeys()); + assertFalse(new BatchAction(batch1, node, false).supportsGeneratedKeys(true)); + } JdbcAdapter buildAdapter(boolean supportGeneratedKeys) {