Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement java.sql.ResultSet #30

Merged
Merged
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
7c20f05
implement java.sql.ResultSet
NathanQingyangXu Jan 28, 2025
20f375d
use the new TODO tag
NathanQingyangXu Jan 29, 2025
b899e85
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Jan 29, 2025
a40105a
finish implementing MongoConnection#prepareStatement(String,int,int)
NathanQingyangXu Jan 31, 2025
12beda0
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 5, 2025
e3f881f
sync up with latest main branch
NathanQingyangXu Feb 5, 2025
a16b701
Merge remote-tracking branch 'origin/HIBERNATE-21-implement-resultSet…
NathanQingyangXu Feb 5, 2025
cd5bdba
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 11, 2025
08fcabf
enrich testing cases
NathanQingyangXu Feb 12, 2025
c0208a3
Merge remote-tracking branch 'origin/HIBERNATE-21-implement-resultSet…
NathanQingyangXu Feb 12, 2025
0da5436
make testing more robust by making column ordered randomly both durin…
NathanQingyangXu Feb 12, 2025
e9de245
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 12, 2025
f76b4ba
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 13, 2025
ddeb761
make use of multi-line formatter to fix spotless issue
NathanQingyangXu Feb 13, 2025
3cddf89
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 14, 2025
95d0738
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 15, 2025
206673f
resolve conflict with latest main branch
NathanQingyangXu Feb 15, 2025
f4c8aa6
Update src/integrationTest/java/com/mongodb/hibernate/jdbc/MongoPrepa…
NathanQingyangXu Feb 19, 2025
a8f404d
add try block to ResultSet in MongoPreparedStatementIntegrationTests
NathanQingyangXu Feb 19, 2025
9db8d59
Update src/integrationTest/java/com/mongodb/hibernate/jdbc/MongoState…
NathanQingyangXu Feb 19, 2025
19bf36a
add try block to ResultSet in MongoStatementIntegrationTests; move `r…
NathanQingyangXu Feb 19, 2025
89f0224
remove confusing exception message for MongoResultSet#getObject()
NathanQingyangXu Feb 19, 2025
7edcf71
simplify EXAMPLE_MQL to empty doc in MongoConnectionTests's ResultSet…
NathanQingyangXu Feb 19, 2025
01f7b28
remove confusing `when&&then` without `given` in MongoResultSetTests
NathanQingyangXu Feb 19, 2025
ee4753d
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 19, 2025
ce039be
decrease duplication in MongoResultSetTests's method sources
NathanQingyangXu Feb 20, 2025
6605190
Merge remote-tracking branch 'origin/HIBERNATE-21-implement-resultSet…
NathanQingyangXu Feb 20, 2025
d1497a3
add exhaustive getXXX() unit testing logic
NathanQingyangXu Feb 20, 2025
b745d0d
remove unnecessary usage of `@Nested` in integration testing cases
NathanQingyangXu Feb 20, 2025
f52b570
add round-trip testing case to combine PreparedStatement and ResultSe…
NathanQingyangXu Feb 20, 2025
2f58a9e
change column index checking exception message
NathanQingyangXu Feb 20, 2025
df032c9
change SQLException message in MongoStatement#executeQueryCommand()
NathanQingyangXu Feb 20, 2025
205835c
rename testing case in MongoResultSetTests to testIsIdempotent()
NathanQingyangXu Feb 20, 2025
dbfb4d2
clean up adapter classes; add logic and testing case to close ResultS…
NathanQingyangXu Feb 21, 2025
7b35d61
improve implementation of MongoStatement#executeQueryCommmand by remo…
NathanQingyangXu Feb 21, 2025
d2d16e5
rename CloseTests to ClosedTests and move the close statement as firs…
NathanQingyangXu Feb 21, 2025
b8053b6
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 21, 2025
7a76e79
revert back changes to ResultSetAdapter to avoid touching it again an…
NathanQingyangXu Feb 24, 2025
3de532a
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 25, 2025
4e7074e
fix conflict with latest main branch
NathanQingyangXu Feb 25, 2025
8706876
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 26, 2025
077c5b8
Update src/test/java/com/mongodb/hibernate/jdbc/MongoResultSetTests.java
NathanQingyangXu Feb 26, 2025
1d1a4c4
update based on some code review comments
NathanQingyangXu Feb 26, 2025
8e05feb
Merge remote-tracking branch 'origin/HIBERNATE-21-implement-resultSet…
NathanQingyangXu Feb 26, 2025
7d41973
rename some methods in MongoResultSetTests
NathanQingyangXu Feb 26, 2025
858fc81
refactor the MongoResultSetTests#testGetValues() based on @MethodSource
NathanQingyangXu Feb 27, 2025
d67c0ad
add validation of "false" BsonBoolean in MongoResultSetTests#testGetV…
NathanQingyangXu Feb 27, 2025
cb189c2
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 27, 2025
2da14ed
merge in latest main
NathanQingyangXu Feb 27, 2025
c46f1cf
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Feb 27, 2025
4351449
refactor getters testing avoiding the usage of MethodSource
NathanQingyangXu Feb 27, 2025
5b11a8b
change testing method name from `getOpenPreconditionInvocations`
NathanQingyangXu Feb 27, 2025
54b562f
improve MongoResultSetTests
NathanQingyangXu Feb 27, 2025
936c70a
Merge remote-tracking branch 'origin/HIBERNATE-21-implement-resultSet…
NathanQingyangXu Feb 28, 2025
d084f15
add Getter testing cases into MongoResultSetTests
NathanQingyangXu Feb 28, 2025
88c6ffd
switch to testing mode in Java driver
NathanQingyangXu Mar 3, 2025
c4b0c0b
drop support of the "byte", "short" and "float" sql types for both `M…
NathanQingyangXu Mar 3, 2025
f48a8ce
refactor MongoStatementIntegrationTests and MongoPreparedStatementInt…
NathanQingyangXu Mar 3, 2025
8dc4510
refactor JDBC closed and range checking testing code to align with Mo…
NathanQingyangXu Mar 4, 2025
2a1b128
remove TODO-HIBERNATE-21 comments from MongoStatement
NathanQingyangXu Mar 4, 2025
2a4e40a
add ticket references to `setQueryTimeout()` and `setFetchSize()` imp…
NathanQingyangXu Mar 4, 2025
e02eaf2
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Mar 4, 2025
3793564
resolve conflict with latest main
NathanQingyangXu Mar 4, 2025
a603b25
implemented MongoStatement#getMaxRows() and MongoStatement#setMaxRows…
NathanQingyangXu Mar 4, 2025
a393025
add logic to use maxRows in MongoStatement#executeQueryCommand() and …
NathanQingyangXu Mar 4, 2025
0a16575
addesses two code review comments by Maxim
NathanQingyangXu Mar 6, 2025
9630209
Update src/main/java/com/mongodb/hibernate/jdbc/MongoStatement.java
NathanQingyangXu Mar 6, 2025
fd063a5
improve MongoExtension by creating MongoClient only once for top clas…
NathanQingyangXu Mar 6, 2025
c2bafa6
add parameter setting checking in MongoPreparedStatement#executeQuery…
NathanQingyangXu Mar 6, 2025
8cc2924
add logic to throw SQLException from PreparedStatement for the 4 Stat…
NathanQingyangXu Mar 6, 2025
0cc9784
add logic to ensure last open ResultSet is closed when Statement invo…
NathanQingyangXu Mar 6, 2025
221ba0b
improve coding in MongoStatement#executeQueryCommand()
NathanQingyangXu Mar 6, 2025
df31b39
move `startTransactionIfNeeded` into try block to catch potential Run…
NathanQingyangXu Mar 6, 2025
0ab4e33
rename MongoStatement#getFieldNamesFromProjectDocument to #getFieldNa…
NathanQingyangXu Mar 6, 2025
496192e
remove MongoStatement#setMaxRows() implementation for it is not used …
NathanQingyangXu Mar 6, 2025
cddac5c
remove javadocs from adapter classes; add missing adapter methods in …
NathanQingyangXu Mar 7, 2025
b431e29
remove ResultSetMetadata stuff and leave ticket references to select …
NathanQingyangXu Mar 7, 2025
9bb639b
Update src/main/java/com/mongodb/hibernate/jdbc/MongoResultSet.java
NathanQingyangXu Mar 7, 2025
b2f0dea
make range checking logic consistent between MongoResultSet and Mongo…
NathanQingyangXu Mar 7, 2025
79b79f3
make MongoResultSet checkClosed() method consistent with MongoStateme…
NathanQingyangXu Mar 7, 2025
a3dfdeb
throw exception for MongoResultSet#findColumn until we work on native…
NathanQingyangXu Mar 7, 2025
f0524d0
improve MongoResultSet#close warning message
NathanQingyangXu Mar 7, 2025
afd52f4
rename Function parameter name in MongoResultSet#getValue()
NathanQingyangXu Mar 7, 2025
9a4778b
add missing MongoResultSet#getBytes() implementation
NathanQingyangXu Mar 7, 2025
25db0e1
simplify the implementation of MongoResultSet#wasNull
NathanQingyangXu Mar 7, 2025
221aba5
clean up jdbc classes
NathanQingyangXu Mar 7, 2025
cec455b
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Mar 11, 2025
02ab460
Merge branch 'main' into HIBERNATE-21-implement-resultSet
NathanQingyangXu Mar 12, 2025
2693594
merge in latest main branch
NathanQingyangXu Mar 12, 2025
5fa9c56
code refactor to combine setter and used state into one class in Mong…
NathanQingyangXu Mar 12, 2025
dc816a5
improve the error handling of the 4 forbidden methods accepting SQL i…
NathanQingyangXu Mar 12, 2025
26c0951
add closing last open ResultSet for all execution methods of MongoSta…
NathanQingyangXu Mar 12, 2025
e8f97d5
move `lastReadColumnValueWasNull` assignment statement after `toJavaC…
NathanQingyangXu Mar 12, 2025
b223c10
change logic to thrown exception if some field is missing
NathanQingyangXu Mar 12, 2025
c796b29
change as per review comments
NathanQingyangXu Mar 13, 2025
850259c
add unit testing cases to ensure last open resultSet is closed when e…
NathanQingyangXu Mar 13, 2025
1beded0
Update src/main/java/com/mongodb/hibernate/jdbc/MongoResultSet.java
NathanQingyangXu Mar 13, 2025
8338768
improve fields emptiness checking in MongoResultSet
NathanQingyangXu Mar 13, 2025
4a3840e
add `@DynamicInsert` forbidding logic in MongoAdditionalMappingContri…
NathanQingyangXu Mar 13, 2025
64eb6b7
add logic to add _id unless suppressed or included explicitly already…
NathanQingyangXu Mar 13, 2025
7b53c42
Update src/test/java/com/mongodb/hibernate/jdbc/MongoConnectionTests.…
NathanQingyangXu Mar 14, 2025
1f979df
Update src/test/java/com/mongodb/hibernate/jdbc/MongoStatementTests.java
NathanQingyangXu Mar 14, 2025
7ce1723
Update src/test/java/com/mongodb/hibernate/jdbc/MongoStatementTests.java
NathanQingyangXu Mar 14, 2025
48711ce
made changes as per code review comments
NathanQingyangXu Mar 14, 2025
7ad1c50
Merge remote-tracking branch 'origin/HIBERNATE-21-implement-resultSet…
NathanQingyangXu Mar 14, 2025
b21b3a4
fix a compiling error
NathanQingyangXu Mar 14, 2025
3bd9b5b
fix a spotless issue
NathanQingyangXu Mar 14, 2025
323a09e
further improvements to some jdbc unit testing classes as per code re…
NathanQingyangXu Mar 14, 2025
2daab80
simplify MongoStatement#getFieldNamesFromProjectStage()
NathanQingyangXu Mar 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -17,28 +17,39 @@
package com.mongodb.hibernate.jdbc;

import static com.mongodb.hibernate.internal.MongoConstants.ID_FIELD_NAME;
import static com.mongodb.hibernate.jdbc.MongoStatementIntegrationTests.doAndTerminateTransaction;
import static com.mongodb.hibernate.jdbc.MongoStatementIntegrationTests.doWithSpecifiedAutoCommit;
import static com.mongodb.hibernate.jdbc.MongoStatementIntegrationTests.insertTestData;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Sorts;
import com.mongodb.hibernate.jdbc.MongoStatementIntegrationTests.SqlExecutable;
import com.mongodb.hibernate.junit.InjectMongoCollection;
import com.mongodb.hibernate.junit.MongoExtension;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import org.bson.BsonDocument;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.junit.jupiter.api.AutoClose;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

@ExtendWith(MongoExtension.class)
class MongoPreparedStatementIntegrationTests {
@@ -62,23 +73,145 @@ void beforeEach() {
session = sessionFactory.openSession();
}

@Nested
class ExecuteUpdateTests {
@Test
void testExecuteQuery() {

insertTestData(
session,
"""
{
insert: "books",
documents: [
{ _id: 1, publishYear: 1867, title: "War and Peace", author: "Leo Tolstoy", comment: "reference only", vintage: false },
{ _id: 2, publishYear: 1878, title: "Anna Karenina", author: "Leo Tolstoy", vintage: true, comment: null},
{ _id: 3, publishYear: 1866, author: "Fyodor Dostoevsky", title: "Crime and Punishment", vintage: false, comment: null },
]
}""");

doWorkAwareOfAutoCommit(connection -> {
try (var pstmt = connection.prepareStatement(
"""
{
aggregate: "books",
pipeline: [
{ $match: { author: { $eq: { $undefined: true } } } },
{ $project: { author: 1, _id: 0, vintage: 1, publishYear: 1, comment: 1, title: 1 } }
]
}""")) {

pstmt.setString(1, "Leo Tolstoy");

try (var rs = pstmt.executeQuery()) {

assertTrue(rs.next());
assertAll(
() -> assertEquals("Leo Tolstoy", rs.getString(1)),
() -> assertFalse(rs.getBoolean(2)),
() -> assertEquals(1867, rs.getInt(3)),
() -> assertEquals("reference only", rs.getString(4)),
() -> assertEquals("War and Peace", rs.getString(5)));
assertTrue(rs.next());
assertAll(
() -> assertEquals("Leo Tolstoy", rs.getString(1)),
() -> assertTrue(rs.getBoolean(2)),
() -> assertEquals(1878, rs.getInt(3)),
() -> assertNull(rs.getString(4)),
() -> assertEquals("Anna Karenina", rs.getString(5)));
assertFalse(rs.next());
}
}
});
}

@Test
void testPreparedStatementAndResultSetRoundTrip() {

var random = new Random();

boolean booleanValue = random.nextBoolean();
double doubleValue = random.nextDouble();
int intValue = random.nextInt();
long longValue = random.nextLong();

byte[] bytes = new byte[64];
random.nextBytes(bytes);
String stringValue = new String(bytes);

BigDecimal bigDecimalValue = new BigDecimal(random.nextInt());

doWorkAwareOfAutoCommit(connection -> {
try (var pstmt = connection.prepareStatement(
"""
{
insert: "books",
documents: [
{
_id: 1,
booleanField: { $undefined: true },
doubleField: { $undefined: true },
intField: { $undefined: true },
longField: { $undefined: true },
stringField: { $undefined: true },
bigDecimalField: { $undefined: true },
bytesField: { $undefined: true }
}
]
}""")) {

pstmt.setBoolean(1, booleanValue);
pstmt.setDouble(2, doubleValue);
pstmt.setInt(3, intValue);
pstmt.setLong(4, longValue);
pstmt.setString(5, stringValue);
pstmt.setBigDecimal(6, bigDecimalValue);
pstmt.setBytes(7, bytes);

pstmt.executeUpdate();
}
});

@BeforeEach
void beforeEach() {
session.doWork(conn -> {
conn.createStatement()
.executeUpdate(
"""
doWorkAwareOfAutoCommit(connection -> {
try (var pstmt = connection.prepareStatement(
"""
{
aggregate: "books",
pipeline: [
{ $match: { _id: { $eq: { $undefined: true } } } },
{ $project:
{
delete: "books",
deletes: [
{ q: {}, limit: 0 }
]
}""");
});
}
_id: 0,
booleanField: 1,
doubleField: 1,
intField: 1,
longField: 1,
stringField: 1,
bigDecimalField: 1,
bytesField: 1
}
}
]
}""")) {

pstmt.setInt(1, 1);
try (var rs = pstmt.executeQuery()) {

assertTrue(rs.next());
assertAll(
() -> assertEquals(booleanValue, rs.getBoolean(1)),
() -> assertEquals(doubleValue, rs.getDouble(2)),
() -> assertEquals(intValue, rs.getInt(3)),
() -> assertEquals(longValue, rs.getLong(4)),
() -> assertEquals(stringValue, rs.getString(5)),
() -> assertEquals(bigDecimalValue, rs.getBigDecimal(6)),
() -> assertArrayEquals(bytes, rs.getBytes(7)));
assertFalse(rs.next());
}
}
});
}

@Nested
class ExecuteUpdateTests {

private static final String INSERT_MQL =
"""
@@ -109,11 +242,51 @@ void beforeEach() {
]
}""";

@ParameterizedTest
@ValueSource(booleans = {true, false})
void testUpdate(boolean autoCommit) {
@Test
void testInsert() {
Function<Connection, MongoPreparedStatement> pstmtProvider = connection -> {
try {
var pstmt = (MongoPreparedStatement)
connection.prepareStatement(
"""
{
insert: "books",
documents: [
{
_id: 1,
title: {$undefined: true},
author: {$undefined: true},
outOfStock: false,
tags: [ "classic", "tolstoy" ]
}
]
}""");
pstmt.setString(1, "War and Peace");
pstmt.setString(2, "Leo Tolstoy");
return pstmt;
} catch (SQLException e) {
throw new RuntimeException(e);
}
};
assertExecuteUpdate(
pstmtProvider,
1,
List.of(
BsonDocument.parse(
"""
{
_id: 1,
title: "War and Peace",
author: "Leo Tolstoy",
outOfStock: false,
tags: [ "classic", "tolstoy" ]
}""")));
}

@Test
void testUpdate() {

prepareData();
insertTestData(session, INSERT_MQL);

var expectedDocs = List.of(
BsonDocument.parse(
@@ -171,36 +344,67 @@ void testUpdate(boolean autoCommit) {
throw new RuntimeException(e);
}
};
assertExecuteUpdate(pstmtProvider, autoCommit, 2, expectedDocs);
assertExecuteUpdate(pstmtProvider, 2, expectedDocs);
}

private void prepareData() {
session.doWork(connection -> {
connection.setAutoCommit(true);
var statement = connection.createStatement();
statement.executeUpdate(INSERT_MQL);
});
@Test
void testDelete() {
insertTestData(session, INSERT_MQL);

Function<Connection, MongoPreparedStatement> pstmtProvider = connection -> {
try {
var pstmt = (MongoPreparedStatement)
connection.prepareStatement(
"""
{
delete: "books",
deletes: [
{
q: { author: { $undefined: true } },
limit: 0
}
]
}""");
pstmt.setString(1, "Leo Tolstoy");
return pstmt;
} catch (SQLException e) {
throw new RuntimeException(e);
}
};
assertExecuteUpdate(
pstmtProvider,
2,
List.of(
BsonDocument.parse(
"""
{
_id: 3,
title: "Crime and Punishment",
author: "Fyodor Dostoevsky",
outOfStock: false,
tags: [ "classic", "dostoevsky", "literature" ]
}""")));
}

private void assertExecuteUpdate(
Function<Connection, MongoPreparedStatement> pstmtProvider,
boolean autoCommit,
int expectedUpdatedRowCount,
List<? extends BsonDocument> expectedDocuments) {
session.doWork(connection -> {
connection.setAutoCommit(autoCommit);
doWorkAwareOfAutoCommit(connection -> {
try (var pstmt = pstmtProvider.apply(connection)) {
try {
assertEquals(expectedUpdatedRowCount, pstmt.executeUpdate());
} finally {
if (!autoCommit) {
connection.commit();
}
}
assertThat(mongoCollection.find().sort(Sorts.ascending(ID_FIELD_NAME)))
.containsExactlyElementsOf(expectedDocuments);
assertEquals(expectedUpdatedRowCount, pstmt.executeUpdate());
}
});
assertThat(mongoCollection.find().sort(Sorts.ascending(ID_FIELD_NAME)))
.containsExactlyElementsOf(expectedDocuments);
}
}

private void doWorkAwareOfAutoCommit(Work work) {
session.doWork(connection -> doAwareOfAutoCommit(connection, () -> work.execute(connection)));
}

void doAwareOfAutoCommit(Connection connection, SqlExecutable work) throws SQLException {
doWithSpecifiedAutoCommit(false, connection, () -> doAndTerminateTransaction(connection, work));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2024-present MongoDB, Inc.
*
* 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.mongodb.hibernate.jdbc;

import static com.mongodb.hibernate.jdbc.MongoStatementIntegrationTests.doWithSpecifiedAutoCommit;

import com.mongodb.hibernate.jdbc.MongoStatementIntegrationTests.SqlExecutable;
import java.sql.Connection;
import java.sql.SQLException;

class MongoPreparedStatementWithAutoCommitIntegrationTests extends MongoPreparedStatementIntegrationTests {
@Override
void doAwareOfAutoCommit(Connection connection, SqlExecutable work) throws SQLException {
doWithSpecifiedAutoCommit(true, connection, work);
}
}
Loading