Skip to content

Commit d102dcb

Browse files
committed
#845 Fix NullPointerException in getGeneratedKeys with blob columns after (auto)commit
(backport of #844)
1 parent eff1c0b commit d102dcb

27 files changed

+189
-52
lines changed

src/jna-client/org/firebirdsql/gds/ng/jna/JnaBlob.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ public class JnaBlob extends AbstractFbBlob implements FbBlob, DatabaseListener
6363
* @param blobParameterBuffer
6464
* blob parameter buffer
6565
*/
66-
public JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer) {
66+
public JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer)
67+
throws SQLException {
6768
this(database, transaction, blobParameterBuffer, NO_BLOB_ID, true);
6869
}
6970

@@ -80,12 +81,12 @@ public JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBu
8081
* blob id
8182
*/
8283
public JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer,
83-
long blobId) {
84+
long blobId) throws SQLException {
8485
this(database, transaction, blobParameterBuffer, blobId, false);
8586
}
8687

8788
private JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer,
88-
long blobId, boolean outputBlob) {
89+
long blobId, boolean outputBlob) throws SQLException {
8990
super(database, transaction, blobParameterBuffer);
9091
this.blobId = new LongByReference(blobId);
9192
this.outputBlob = outputBlob;

src/jna-client/org/firebirdsql/gds/ng/jna/JnaDatabase.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,14 +295,16 @@ public JnaStatement createStatement(FbTransaction transaction) throws SQLExcepti
295295
}
296296

297297
@Override
298-
public FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) {
298+
public FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer)
299+
throws SQLException {
299300
final JnaBlob jnaBlob = new JnaBlob(this, (JnaTransaction) transaction, blobParameterBuffer);
300301
jnaBlob.addExceptionListener(exceptionListenerDispatcher);
301302
return jnaBlob;
302303
}
303304

304305
@Override
305-
public FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId) {
306+
public FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId)
307+
throws SQLException {
306308
final JnaBlob jnaBlob = new JnaBlob(this, (JnaTransaction) transaction, blobParameterBuffer, blobId);
307309
jnaBlob.addExceptionListener(exceptionListenerDispatcher);
308310
return jnaBlob;

src/main/org/firebirdsql/gds/ng/AbstractFbBlob.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,12 @@ public abstract class AbstractFbBlob implements FbBlob, TransactionListener, Dat
4848
private boolean eof;
4949
private SQLException deferredException;
5050

51-
protected AbstractFbBlob(FbDatabase database, FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) {
51+
protected AbstractFbBlob(FbDatabase database, FbTransaction transaction, BlobParameterBuffer blobParameterBuffer)
52+
throws SQLException {
5253
this.database = database;
5354
this.transaction = transaction;
55+
checkDatabaseAttached();
56+
checkTransactionActive();
5457
this.blobParameterBuffer = blobParameterBuffer;
5558
transaction.addWeakTransactionListener(this);
5659
}
@@ -364,17 +367,17 @@ protected final boolean isEndingTransaction() {
364367

365368
/**
366369
* @throws java.sql.SQLException
367-
* When no transaction is set, or the transaction state is not {@link TransactionState#ACTIVE}
370+
* when no transaction is set, or the transaction state is not {@link TransactionState#ACTIVE}
368371
*/
369372
protected final void checkTransactionActive() throws SQLException {
370373
TransactionHelper.checkTransactionActive(getTransaction(), ISCConstants.isc_segstr_no_trans);
371374
}
372375

373376
/**
374377
* @throws SQLException
375-
* When no database is set, or the database is not attached
378+
* when no database is set, or the database is not attached
376379
*/
377-
protected void checkDatabaseAttached() throws SQLException {
380+
protected final void checkDatabaseAttached() throws SQLException {
378381
FbDatabase database = this.database;
379382
if (database == null || !database.isAttached()) {
380383
throw new FbExceptionBuilder().nonTransientException(ISCConstants.isc_segstr_wrong_db).toSQLException();

src/main/org/firebirdsql/gds/ng/FbDatabase.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,10 @@ public interface FbDatabase extends FbAttachment {
129129
* @param blobParameterBuffer
130130
* blob parameter buffer
131131
* @return instance of {@link FbBlob}
132+
* @throws SQLException
133+
* if the database is not attached or the transaction is not active
132134
*/
133-
FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer);
135+
FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) throws SQLException;
134136

135137
/**
136138
* Creates a blob for write access to a new blob on the server.
@@ -145,9 +147,11 @@ public interface FbDatabase extends FbAttachment {
145147
* @param transaction
146148
* transaction associated with the blob
147149
* @return instance of {@link FbBlob}
150+
* @throws SQLException
151+
* if the database is not attached or the transaction is not active
148152
* @since 5
149153
*/
150-
default FbBlob createBlobForOutput(FbTransaction transaction) {
154+
default FbBlob createBlobForOutput(FbTransaction transaction) throws SQLException {
151155
return createBlobForOutput(transaction, (BlobParameterBuffer) null);
152156
}
153157

@@ -162,9 +166,11 @@ default FbBlob createBlobForOutput(FbTransaction transaction) {
162166
* @param blobConfig
163167
* blob config (cannot be {@code null})
164168
* @return instance of {@link FbBlob}
169+
* @throws SQLException
170+
* if the database is not attached or the transaction is not active
165171
* @since 5
166172
*/
167-
default FbBlob createBlobForOutput(FbTransaction transaction, BlobConfig blobConfig) {
173+
default FbBlob createBlobForOutput(FbTransaction transaction, BlobConfig blobConfig) throws SQLException {
168174
BlobParameterBuffer blobParameterBuffer = createBlobParameterBuffer();
169175
blobConfig.writeOutputConfig(blobParameterBuffer);
170176
return createBlobForOutput(transaction, blobParameterBuffer);
@@ -183,8 +189,11 @@ default FbBlob createBlobForOutput(FbTransaction transaction, BlobConfig blobCon
183189
* @param blobId
184190
* id of the blob
185191
* @return instance of {@link FbBlob}
192+
* @throws SQLException
193+
* if the database is not attached or the transaction is not active
186194
*/
187-
FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId);
195+
FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId)
196+
throws SQLException;
188197

189198
/**
190199
* Creates a blob for read access to an existing blob on the server.
@@ -201,9 +210,11 @@ default FbBlob createBlobForOutput(FbTransaction transaction, BlobConfig blobCon
201210
* @param blobId
202211
* id of the blob
203212
* @return instance of {@link FbBlob}
213+
* @throws SQLException
214+
* if the database is not attached or the transaction is not active
204215
* @since 5
205216
*/
206-
default FbBlob createBlobForInput(FbTransaction transaction, long blobId) {
217+
default FbBlob createBlobForInput(FbTransaction transaction, long blobId) throws SQLException {
207218
return createBlobForInput(transaction, (BlobParameterBuffer) null, blobId);
208219
}
209220

@@ -221,8 +232,11 @@ default FbBlob createBlobForInput(FbTransaction transaction, long blobId) {
221232
* handle id of the blob
222233
* @return instance of {@link FbBlob}
223234
* @since 5
235+
* @throws SQLException
236+
* if the database is not attached or the transaction is not active
224237
*/
225-
default FbBlob createBlobForInput(FbTransaction transaction, BlobConfig blobConfig, long blobId) {
238+
default FbBlob createBlobForInput(FbTransaction transaction, BlobConfig blobConfig, long blobId)
239+
throws SQLException {
226240
BlobParameterBuffer blobParameterBuffer = createBlobParameterBuffer();
227241
blobConfig.writeInputConfig(blobParameterBuffer);
228242
return createBlobForInput(transaction, blobParameterBuffer, blobId);

src/main/org/firebirdsql/gds/ng/wire/AbstractFbWireBlob.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public abstract class AbstractFbWireBlob extends AbstractFbBlob implements FbWir
4747
private int blobHandle;
4848

4949
protected AbstractFbWireBlob(FbWireDatabase database, FbWireTransaction transaction,
50-
BlobParameterBuffer blobParameterBuffer) {
50+
BlobParameterBuffer blobParameterBuffer) throws SQLException {
5151
super(database, transaction, blobParameterBuffer);
5252
}
5353

src/main/org/firebirdsql/gds/ng/wire/AbstractFbWireDatabase.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ public void setNetworkTimeout(int milliseconds) throws SQLException {
178178
}
179179

180180
@Override
181-
public final FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) {
181+
public final FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer)
182+
throws SQLException {
182183
final FbWireBlob outputBlob =
183184
protocolDescriptor.createOutputBlob(this, (FbWireTransaction) transaction, blobParameterBuffer);
184185
outputBlob.addExceptionListener(exceptionListenerDispatcher);
@@ -187,7 +188,7 @@ public final FbBlob createBlobForOutput(FbTransaction transaction, BlobParameter
187188

188189
@Override
189190
public final FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer,
190-
long blobId) {
191+
long blobId) throws SQLException {
191192
final FbWireBlob inputBlob =
192193
protocolDescriptor.createInputBlob(this, (FbWireTransaction) transaction, blobParameterBuffer, blobId);
193194
inputBlob.addExceptionListener(exceptionListenerDispatcher);

src/main/org/firebirdsql/gds/ng/wire/AbstractFbWireInputBlob.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public abstract class AbstractFbWireInputBlob extends AbstractFbWireBlob {
3333
private final long blobId;
3434

3535
protected AbstractFbWireInputBlob(FbWireDatabase database, FbWireTransaction transaction,
36-
BlobParameterBuffer blobParameterBuffer, long blobId) {
36+
BlobParameterBuffer blobParameterBuffer, long blobId) throws SQLException {
3737
super(database, transaction, blobParameterBuffer);
3838
this.blobId = blobId;
3939
}

src/main/org/firebirdsql/gds/ng/wire/AbstractFbWireOutputBlob.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public abstract class AbstractFbWireOutputBlob extends AbstractFbWireBlob {
3636
private long blobId;
3737

3838
protected AbstractFbWireOutputBlob(FbWireDatabase database, FbWireTransaction transaction,
39-
BlobParameterBuffer blobParameterBuffer) {
39+
BlobParameterBuffer blobParameterBuffer) throws SQLException {
4040
super(database, transaction, blobParameterBuffer);
4141
}
4242

src/main/org/firebirdsql/gds/ng/wire/ProtocolDescriptor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public interface ProtocolDescriptor {
183183
* @return FbWireBlob implementation
184184
*/
185185
FbWireBlob createOutputBlob(FbWireDatabase database, FbWireTransaction transaction,
186-
BlobParameterBuffer blobParameterBuffer);
186+
BlobParameterBuffer blobParameterBuffer) throws SQLException;
187187

188188
/**
189189
* Create an input {@link FbWireBlob} implementation for this protocol version.
@@ -199,7 +199,7 @@ FbWireBlob createOutputBlob(FbWireDatabase database, FbWireTransaction transacti
199199
* @return FbWireBlob implementation
200200
*/
201201
FbWireBlob createInputBlob(FbWireDatabase database, FbWireTransaction transaction,
202-
BlobParameterBuffer blobParameterBuffer, long blobId);
202+
BlobParameterBuffer blobParameterBuffer, long blobId) throws SQLException;
203203

204204
/**
205205
* Create a disconnected asynchronous channel.

src/main/org/firebirdsql/gds/ng/wire/version10/V10InputBlob.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public class V10InputBlob extends AbstractFbWireInputBlob implements FbWireBlob,
4545
// TODO V10OutputBlob and V10InputBlob share some common behavior and information (eg in open() and getMaximumSegmentSize()), find a way to unify this
4646

4747
public V10InputBlob(FbWireDatabase database, FbWireTransaction transaction,
48-
BlobParameterBuffer blobParameterBuffer, long blobId) {
48+
BlobParameterBuffer blobParameterBuffer, long blobId) throws SQLException {
4949
super(database, transaction, blobParameterBuffer, blobId);
5050
}
5151

0 commit comments

Comments
 (0)