Skip to content

Commit 0a612c2

Browse files
akappsdaniellansun
authored andcommitted
GROOVY-8288 executeBatch() should not be called with batchCount == 0
(closes #586)
1 parent 70ce561 commit 0a612c2

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

subprojects/groovy-sql/src/main/java/groovy/sql/BatchingStatementWrapper.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ public void clearBatch() throws SQLException {
8383
}
8484

8585
public int[] executeBatch() throws SQLException {
86-
int[] lastResult = delegate.executeBatch();
87-
processResult(lastResult);
86+
if (shouldCallDelegate()) {
87+
int[] lastResult = delegate.executeBatch();
88+
processResult(lastResult);
89+
}
8890
int[] result = new int[results.size()];
8991
for (int i = 0; i < results.size(); i++) {
9092
result[i] = results.get(i);
@@ -93,6 +95,17 @@ public int[] executeBatch() throws SQLException {
9395
return result;
9496
}
9597

98+
private boolean shouldCallDelegate() {
99+
if (batchCount > 0) {
100+
return true;
101+
} else if (results.isEmpty()) {
102+
log.warning("Nothing has been added to batch. This might cause the JDBC driver to throw an exception.");
103+
return true;
104+
}
105+
// Nothing added since last delegate execution. No need to call the delegate this time.
106+
return false;
107+
}
108+
96109
protected void processResult(int[] lastResult) {
97110
boolean foundError = false;
98111
for (int i : lastResult) {

subprojects/groovy-sql/src/test/groovy/groovy/sql/SqlBatchTest.groovy

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package groovy.sql
2020

21+
import groovy.test.GroovyAssert
22+
2123
import javax.sql.DataSource
2224

2325
import static groovy.sql.SqlTestConstants.*
@@ -119,6 +121,44 @@ class SqlBatchTest extends GroovyTestCase {
119121
// FINE: Successfully executed batch with 1 command(s)
120122
}
121123

124+
void testWithBatchHavingSizeSameSizeAsStatements() {
125+
def numRows = sql.rows("SELECT * FROM PERSON").size()
126+
assert numRows == 3
127+
def myOthers = ['f4':'l4','f5':'l5','f6':'l6','f7':'l7']
128+
def result = sql.withBatch(myOthers.size(), "insert into PERSON (id, firstname, lastname) values (?, ?, ?)") { ps ->
129+
myOthers.eachWithIndex { k, v, index ->
130+
def id = index + numRows + 1
131+
ps.addBatch(id, k, v)
132+
}
133+
}
134+
assert result == [1] * myOthers.size()
135+
assert sql.rows("SELECT * FROM PERSON").size() == numRows + myOthers.size()
136+
// end result the same as if no batching was in place but logging should show:
137+
// FINE: Successfully executed batch with 4 command(s)
138+
}
139+
140+
void testWithBatchNothingAddedToBatch() {
141+
def numRows = sql.rows("SELECT * FROM PERSON").size()
142+
assert numRows == 3
143+
144+
def result = sql.withBatch { ps ->
145+
// Add nothing
146+
}
147+
assert result == [] as int[]
148+
}
149+
150+
void testWithBatchWithPreparedStatementNothingAddedToBatch() {
151+
def numRows = sql.rows("SELECT * FROM PERSON").size()
152+
assert numRows == 3
153+
154+
// If you create a PreparedStatement you have to use it - or else HSQL throws an exception
155+
GroovyAssert.shouldFail {
156+
sql.withBatch(3, "insert into PERSON (id, firstname, lastname) values (?, ?, ?)") { ps ->
157+
// Add nothing - not a good practice at all...
158+
}
159+
}
160+
}
161+
122162
void testWithBatchInsideWithTransaction() {
123163
def numRows = sql.rows("SELECT * FROM PERSON").size()
124164
assert numRows == 3

0 commit comments

Comments
 (0)