CAY-2650 Support using generated primary keys along with batch inserts
Fixed unit tests for Derby and MSSQL
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 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 @@
: 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 @@
*/
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 @@
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 @@
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 @@
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) {