Skip to content

Commit 39eedb1

Browse files
committed
#844 Fix NullPointerException in getGeneratedKeys with blob columns after (auto)commit
1 parent 48d132b commit 39eedb1

27 files changed

+223
-85
lines changed

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/JnaBlob.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ public class JnaBlob extends AbstractFbBlob implements FbBlob, DatabaseListener
4848
* @param blobParameterBuffer
4949
* blob parameter buffer
5050
*/
51-
public JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer) {
51+
public JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer)
52+
throws SQLException {
5253
this(database, transaction, blobParameterBuffer, NO_BLOB_ID, true);
5354
}
5455

@@ -65,12 +66,12 @@ public JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBu
6566
* blob id
6667
*/
6768
public JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer,
68-
long blobId) {
69+
long blobId) throws SQLException {
6970
this(database, transaction, blobParameterBuffer, blobId, false);
7071
}
7172

7273
private JnaBlob(JnaDatabase database, JnaTransaction transaction, BlobParameterBuffer blobParameterBuffer,
73-
long blobId, boolean outputBlob) {
74+
long blobId, boolean outputBlob) throws SQLException {
7475
super(database, transaction, blobParameterBuffer);
7576
this.blobId = new LongByReference(blobId);
7677
this.outputBlob = outputBlob;

jaybird-native/src/main/java/org/firebirdsql/gds/ng/jna/JnaDatabase.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright 2014-2024 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2014-2025 Mark Rotteveel
22
// SPDX-FileCopyrightText: Copyright 2016 Adriano dos Santos Fernandes
33
// SPDX-License-Identifier: LGPL-2.1-or-later
44
package org.firebirdsql.gds.ng.jna;
@@ -283,14 +283,16 @@ public JnaStatement createStatement(FbTransaction transaction) throws SQLExcepti
283283
}
284284

285285
@Override
286-
public FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) {
286+
public FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer)
287+
throws SQLException {
287288
final JnaBlob jnaBlob = new JnaBlob(this, (JnaTransaction) transaction, blobParameterBuffer);
288289
jnaBlob.addExceptionListener(exceptionListenerDispatcher);
289290
return jnaBlob;
290291
}
291292

292293
@Override
293-
public FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId) {
294+
public FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId)
295+
throws SQLException {
294296
final JnaBlob jnaBlob = new JnaBlob(this, (JnaTransaction) transaction, blobParameterBuffer, blobId);
295297
jnaBlob.addExceptionListener(exceptionListenerDispatcher);
296298
return jnaBlob;

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

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

41-
protected AbstractFbBlob(FbDatabase database, FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) {
41+
protected AbstractFbBlob(FbDatabase database, FbTransaction transaction, BlobParameterBuffer blobParameterBuffer)
42+
throws SQLException {
4243
this.database = database;
4344
this.transaction = transaction;
45+
checkDatabaseAttached();
46+
checkTransactionActive();
4447
this.blobParameterBuffer = blobParameterBuffer;
4548
maximumSegmentSize = maximumSegmentSize(database);
4649
transaction.addWeakTransactionListener(this);
@@ -386,17 +389,17 @@ protected final boolean isEndingTransaction() {
386389

387390
/**
388391
* @throws java.sql.SQLException
389-
* When no transaction is set, or the transaction state is not {@link TransactionState#ACTIVE}
392+
* when no transaction is set, or the transaction state is not {@link TransactionState#ACTIVE}
390393
*/
391394
protected final void checkTransactionActive() throws SQLException {
392395
TransactionHelper.checkTransactionActive(getTransaction(), ISCConstants.isc_segstr_no_trans);
393396
}
394397

395398
/**
396399
* @throws SQLException
397-
* When no database is set, or the database is not attached
400+
* when no database is set, or the database is not attached
398401
*/
399-
protected void checkDatabaseAttached() throws SQLException {
402+
protected final void checkDatabaseAttached() throws SQLException {
400403
FbDatabase database = this.database;
401404
if (database == null || !database.isAttached()) {
402405
throw FbExceptionBuilder.toNonTransientException(ISCConstants.isc_segstr_wrong_db);

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright 2013-2024 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2013-2025 Mark Rotteveel
22
// SPDX-FileCopyrightText: Copyright 2019 Vasiliy Yashkov
33
// SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause
44
package org.firebirdsql.gds.ng;
@@ -120,8 +120,10 @@ public interface FbDatabase extends FbAttachment {
120120
* @param blobParameterBuffer
121121
* blob parameter buffer
122122
* @return instance of {@link FbBlob}
123+
* @throws SQLException
124+
* if the database is not attached or the transaction is not active
123125
*/
124-
FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer);
126+
FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) throws SQLException;
125127

126128
/**
127129
* Creates a blob for write access to a new blob on the server.
@@ -136,9 +138,11 @@ public interface FbDatabase extends FbAttachment {
136138
* @param transaction
137139
* transaction associated with the blob
138140
* @return instance of {@link FbBlob}
141+
* @throws SQLException
142+
* if the database is not attached or the transaction is not active
139143
* @since 5
140144
*/
141-
default FbBlob createBlobForOutput(FbTransaction transaction) {
145+
default FbBlob createBlobForOutput(FbTransaction transaction) throws SQLException {
142146
return createBlobForOutput(transaction, (BlobParameterBuffer) null);
143147
}
144148

@@ -153,9 +157,11 @@ default FbBlob createBlobForOutput(FbTransaction transaction) {
153157
* @param blobConfig
154158
* blob config (cannot be {@code null})
155159
* @return instance of {@link FbBlob}
160+
* @throws SQLException
161+
* if the database is not attached or the transaction is not active
156162
* @since 5
157163
*/
158-
default FbBlob createBlobForOutput(FbTransaction transaction, BlobConfig blobConfig) {
164+
default FbBlob createBlobForOutput(FbTransaction transaction, BlobConfig blobConfig) throws SQLException {
159165
BlobParameterBuffer blobParameterBuffer = createBlobParameterBuffer();
160166
blobConfig.writeOutputConfig(blobParameterBuffer);
161167
return createBlobForOutput(transaction, blobParameterBuffer);
@@ -174,8 +180,11 @@ default FbBlob createBlobForOutput(FbTransaction transaction, BlobConfig blobCon
174180
* @param blobId
175181
* id of the blob
176182
* @return instance of {@link FbBlob}
183+
* @throws SQLException
184+
* if the database is not attached or the transaction is not active
177185
*/
178-
FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId);
186+
FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer, long blobId)
187+
throws SQLException;
179188

180189
/**
181190
* Creates a blob for read access to an existing blob on the server.
@@ -192,9 +201,11 @@ default FbBlob createBlobForOutput(FbTransaction transaction, BlobConfig blobCon
192201
* @param blobId
193202
* id of the blob
194203
* @return instance of {@link FbBlob}
204+
* @throws SQLException
205+
* if the database is not attached or the transaction is not active
195206
* @since 5
196207
*/
197-
default FbBlob createBlobForInput(FbTransaction transaction, long blobId) {
208+
default FbBlob createBlobForInput(FbTransaction transaction, long blobId) throws SQLException {
198209
return createBlobForInput(transaction, (BlobParameterBuffer) null, blobId);
199210
}
200211

@@ -211,9 +222,12 @@ default FbBlob createBlobForInput(FbTransaction transaction, long blobId) {
211222
* @param blobId
212223
* handle id of the blob
213224
* @return instance of {@link FbBlob}
225+
* @throws SQLException
226+
* if the database is not attached or the transaction is not active
214227
* @since 5
215228
*/
216-
default FbBlob createBlobForInput(FbTransaction transaction, BlobConfig blobConfig, long blobId) {
229+
default FbBlob createBlobForInput(FbTransaction transaction, BlobConfig blobConfig, long blobId)
230+
throws SQLException {
217231
BlobParameterBuffer blobParameterBuffer = createBlobParameterBuffer();
218232
blobConfig.writeInputConfig(blobParameterBuffer);
219233
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
@@ -29,7 +29,7 @@ public abstract class AbstractFbWireBlob extends AbstractFbBlob implements FbWir
2929
private int blobHandle;
3030

3131
protected AbstractFbWireBlob(FbWireDatabase database, FbWireTransaction transaction,
32-
BlobParameterBuffer blobParameterBuffer) {
32+
BlobParameterBuffer blobParameterBuffer) throws SQLException {
3333
super(database, transaction, blobParameterBuffer);
3434
}
3535

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

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

172172
@Override
173-
public final FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer) {
173+
public final FbBlob createBlobForOutput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer)
174+
throws SQLException {
174175
final FbWireBlob outputBlob =
175176
protocolDescriptor.createOutputBlob(this, (FbWireTransaction) transaction, blobParameterBuffer);
176177
outputBlob.addExceptionListener(exceptionListenerDispatcher);
@@ -179,7 +180,7 @@ public final FbBlob createBlobForOutput(FbTransaction transaction, BlobParameter
179180

180181
@Override
181182
public final FbBlob createBlobForInput(FbTransaction transaction, BlobParameterBuffer blobParameterBuffer,
182-
long blobId) {
183+
long blobId) throws SQLException {
183184
final FbWireBlob inputBlob =
184185
protocolDescriptor.createInputBlob(this, (FbWireTransaction) transaction, blobParameterBuffer, blobId);
185186
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
@@ -17,7 +17,7 @@ public abstract class AbstractFbWireInputBlob extends AbstractFbWireBlob {
1717
private final long blobId;
1818

1919
protected AbstractFbWireInputBlob(FbWireDatabase database, FbWireTransaction transaction,
20-
BlobParameterBuffer blobParameterBuffer, long blobId) {
20+
BlobParameterBuffer blobParameterBuffer, long blobId) throws SQLException {
2121
super(database, transaction, blobParameterBuffer);
2222
this.blobId = blobId;
2323
}

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

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

2222
protected AbstractFbWireOutputBlob(FbWireDatabase database, FbWireTransaction transaction,
23-
BlobParameterBuffer blobParameterBuffer) {
23+
BlobParameterBuffer blobParameterBuffer) throws SQLException {
2424
super(database, transaction, blobParameterBuffer);
2525
}
2626

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright 2013-2024 Mark Rotteveel
1+
// SPDX-FileCopyrightText: Copyright 2013-2025 Mark Rotteveel
22
// SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause
33
package org.firebirdsql.gds.ng.wire;
44

@@ -159,9 +159,11 @@ public interface ProtocolDescriptor {
159159
* @param blobParameterBuffer
160160
* Blob Parameter Buffer
161161
* @return FbWireBlob implementation
162+
* @throws SQLException
163+
* if the database is not attached or the transaction is not active
162164
*/
163165
FbWireBlob createOutputBlob(FbWireDatabase database, FbWireTransaction transaction,
164-
BlobParameterBuffer blobParameterBuffer);
166+
BlobParameterBuffer blobParameterBuffer) throws SQLException;
165167

166168
/**
167169
* Create an input {@link FbWireBlob} implementation for this protocol version.
@@ -175,9 +177,11 @@ FbWireBlob createOutputBlob(FbWireDatabase database, FbWireTransaction transacti
175177
* @param blobId
176178
* Blob Id (must be non-zero for input blob)
177179
* @return FbWireBlob implementation
180+
* @throws SQLException
181+
* if the database is not attached or the transaction is not active
178182
*/
179183
FbWireBlob createInputBlob(FbWireDatabase database, FbWireTransaction transaction,
180-
BlobParameterBuffer blobParameterBuffer, long blobId);
184+
BlobParameterBuffer blobParameterBuffer, long blobId) throws SQLException;
181185

182186
/**
183187
* 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
@@ -32,7 +32,7 @@ public class V10InputBlob extends AbstractFbWireInputBlob implements FbWireBlob,
3232
// TODO V10OutputBlob and V10InputBlob share some common behavior and information (eg in open() and getMaximumSegmentSize()), find a way to unify this
3333

3434
public V10InputBlob(FbWireDatabase database, FbWireTransaction transaction, BlobParameterBuffer blobParameterBuffer,
35-
long blobId) {
35+
long blobId) throws SQLException {
3636
super(database, transaction, blobParameterBuffer, blobId);
3737
}
3838

0 commit comments

Comments
 (0)