@@ -50,12 +50,8 @@ public final class ResourceRegistryStandardImpl implements ResourceRegistry {
50
50
private final JdbcEventHandler jdbcEventHandler ;
51
51
52
52
private final HashMap <Statement , HashMap <ResultSet ,Object >> xref = new HashMap <>();
53
- private HashMap <ResultSet ,Object > unassociatedResultSets ;
54
-
55
- private ArrayList <Blob > blobs ;
56
- private ArrayList <Clob > clobs ;
57
- private ArrayList <NClob > nclobs ;
58
53
54
+ private ExtendedState ext ;
59
55
private Statement lastQuery ;
60
56
61
57
public ResourceRegistryStandardImpl () {
@@ -69,10 +65,7 @@ public ResourceRegistryStandardImpl(JdbcEventHandler jdbcEventHandler) {
69
65
@ Override
70
66
public boolean hasRegisteredResources () {
71
67
return hasRegistered ( xref )
72
- || hasRegistered ( unassociatedResultSets )
73
- || hasRegistered ( blobs )
74
- || hasRegistered ( clobs )
75
- || hasRegistered ( nclobs );
68
+ || ext != null && ext .hasRegisteredResources ();
76
69
}
77
70
78
71
@ Override
@@ -142,9 +135,8 @@ public void release(ResultSet resultSet, Statement statement) {
142
135
}
143
136
}
144
137
else {
145
- final Object removed = unassociatedResultSets == null ? null : unassociatedResultSets .remove ( resultSet );
146
- if ( removed == null ) {
147
- log .unregisteredResultSetWithoutStatement ();
138
+ if ( ext != null ) {
139
+ ext .releaseUnassociatedResult ( resultSet );
148
140
}
149
141
}
150
142
close ( resultSet );
@@ -241,11 +233,15 @@ public void register(ResultSet resultSet, Statement statement) {
241
233
resultSets .put ( resultSet , PRESENT );
242
234
}
243
235
else {
244
- if ( unassociatedResultSets == null ) {
245
- this .unassociatedResultSets = new HashMap <>();
246
- }
247
- unassociatedResultSets .put ( resultSet , PRESENT );
236
+ getExtendedStateForWrite ().storeUnassociatedResultset ( resultSet );
237
+ }
238
+ }
239
+
240
+ private ExtendedState getExtendedStateForWrite () {
241
+ if ( this .ext == null ) {
242
+ this .ext = new ExtendedState ();
248
243
}
244
+ return this .ext ;
249
245
}
250
246
251
247
private JDBCException convert (SQLException e , String s ) {
@@ -254,56 +250,46 @@ private JDBCException convert(SQLException e, String s) {
254
250
255
251
@ Override
256
252
public void register (Blob blob ) {
257
- if ( blobs == null ) {
258
- blobs = new ArrayList <>();
259
- }
260
-
261
- blobs .add ( blob );
253
+ getExtendedStateForWrite ().registerBlob ( blob );
262
254
}
263
255
264
256
@ Override
265
- public void release (Blob blob ) {
266
- if ( blobs == null ) {
257
+ public void release (final Blob blob ) {
258
+ if ( ext == null || ext . blobs == null ) {
267
259
log .debug ( "Request to release Blob, but appears no Blobs have ever been registered" );
268
260
return ;
269
261
}
270
- blobs .remove ( blob );
262
+ ext . blobs .remove ( blob );
271
263
}
272
264
273
265
@ Override
274
- public void register (Clob clob ) {
275
- if ( clobs == null ) {
276
- clobs = new ArrayList <>();
277
- }
278
- clobs .add ( clob );
266
+ public void register (final Clob clob ) {
267
+ getExtendedStateForWrite ().registerClob ( clob );
279
268
}
280
269
281
270
@ Override
282
- public void release (Clob clob ) {
283
- if ( clobs == null ) {
271
+ public void release (final Clob clob ) {
272
+ if ( ext == null || ext . clobs == null ) {
284
273
log .debug ( "Request to release Clob, but appears no Clobs have ever been registered" );
285
274
return ;
286
275
}
287
- clobs .remove ( clob );
276
+ ext . clobs .remove ( clob );
288
277
}
289
278
290
279
@ Override
291
- public void register (NClob nclob ) {
280
+ public void register (final NClob nclob ) {
292
281
// todo : just store them in clobs?
293
- if ( nclobs == null ) {
294
- nclobs = new ArrayList <>();
295
- }
296
- nclobs .add ( nclob );
282
+ getExtendedStateForWrite ().registerNClob ( nclob );
297
283
}
298
284
299
285
@ Override
300
286
public void release (NClob nclob ) {
301
287
// todo : just store them in clobs?
302
- if ( nclobs == null ) {
288
+ if ( ext == null || ext . nclobs == null ) {
303
289
log .debug ( "Request to release NClob, but appears no NClobs have ever been registered" );
304
290
return ;
305
291
}
306
- nclobs .remove ( nclob );
292
+ ext . nclobs .remove ( nclob );
307
293
}
308
294
309
295
@ Override
@@ -332,55 +318,118 @@ public void releaseResources() {
332
318
xref .forEach ( ResourceRegistryStandardImpl ::releaseXref );
333
319
xref .clear ();
334
320
335
- closeAll ( unassociatedResultSets );
336
-
337
- if ( blobs != null ) {
338
- blobs .forEach ( blob -> {
339
- try {
340
- blob .free ();
341
- }
342
- catch (SQLException e ) {
343
- log .debugf ( "Unable to free JDBC Blob reference [%s]" , e .getMessage () );
344
- }
345
- } );
346
- //for these, it seems better to null the map rather than clear it:
347
- blobs = null ;
348
- }
349
-
350
- if ( clobs != null ) {
351
- clobs .forEach ( clob -> {
352
- try {
353
- clob .free ();
354
- }
355
- catch (SQLException e ) {
356
- log .debugf ( "Unable to free JDBC Clob reference [%s]" , e .getMessage () );
357
- }
358
- } );
359
- clobs = null ;
360
- }
361
-
362
- if ( nclobs != null ) {
363
- nclobs .forEach ( nclob -> {
364
- try {
365
- nclob .free ();
366
- }
367
- catch (SQLException e ) {
368
- log .debugf ( "Unable to free JDBC NClob reference [%s]" , e .getMessage () );
369
- }
370
- } );
371
- nclobs = null ;
321
+ if ( ext != null ) {
322
+ ext .releaseResources ();
372
323
}
373
324
374
325
if ( jdbcEventHandler != null ) {
375
326
jdbcEventHandler .jdbcReleaseRegistryResourcesEnd ();
376
327
}
377
328
}
378
329
379
- private boolean hasRegistered (final HashMap resource ) {
330
+ private static boolean hasRegistered (final HashMap resource ) {
380
331
return resource != null && !resource .isEmpty ();
381
332
}
382
333
383
- private boolean hasRegistered (final ArrayList resource ) {
334
+ private static boolean hasRegistered (final ArrayList resource ) {
384
335
return resource != null && !resource .isEmpty ();
385
336
}
337
+
338
+ /**
339
+ * Keeping this state separate from the main instance state as these are less-so commonly
340
+ * used: this keeps memory pressure low and the code a bit more organized.
341
+ * This implies that instances of ExtendedState should be lazily initialized, and access
342
+ * carefully guarded against null.
343
+ */
344
+ private static class ExtendedState {
345
+ //All fields lazily initialized as well:
346
+ private HashMap <ResultSet ,Object > unassociatedResultSets ;
347
+ private ArrayList <Blob > blobs ;
348
+ private ArrayList <Clob > clobs ;
349
+ private ArrayList <NClob > nclobs ;
350
+
351
+ public boolean hasRegisteredResources () {
352
+ return hasRegistered ( unassociatedResultSets )
353
+ || hasRegistered ( blobs )
354
+ || hasRegistered ( clobs )
355
+ || hasRegistered ( nclobs );
356
+ }
357
+
358
+ public void releaseUnassociatedResult (final ResultSet resultSet ) {
359
+ final Object removed = unassociatedResultSets == null ? null : unassociatedResultSets .remove ( resultSet );
360
+ if ( removed == null ) {
361
+ log .unregisteredResultSetWithoutStatement ();
362
+ }
363
+ }
364
+
365
+ public void storeUnassociatedResultset (ResultSet resultSet ) {
366
+ if ( unassociatedResultSets == null ) {
367
+ this .unassociatedResultSets = new HashMap <>();
368
+ }
369
+ unassociatedResultSets .put ( resultSet , PRESENT );
370
+ }
371
+
372
+ public void registerBlob (final Blob blob ) {
373
+ if ( blobs == null ) {
374
+ blobs = new ArrayList <>();
375
+ }
376
+
377
+ blobs .add ( blob );
378
+ }
379
+
380
+ public void registerClob (final Clob clob ) {
381
+ if ( clobs == null ) {
382
+ clobs = new ArrayList <>();
383
+ }
384
+ clobs .add ( clob );
385
+ }
386
+
387
+ public void registerNClob (final NClob nclob ) {
388
+ if ( nclobs == null ) {
389
+ nclobs = new ArrayList <>();
390
+ }
391
+ nclobs .add ( nclob );
392
+ }
393
+
394
+ public void releaseResources () {
395
+ closeAll ( unassociatedResultSets );
396
+
397
+ if ( blobs != null ) {
398
+ blobs .forEach ( blob -> {
399
+ try {
400
+ blob .free ();
401
+ }
402
+ catch (SQLException e ) {
403
+ log .debugf ( "Unable to free JDBC Blob reference [%s]" , e .getMessage () );
404
+ }
405
+ } );
406
+ //for these, it seems better to null the map rather than clear it:
407
+ blobs = null ;
408
+ }
409
+
410
+ if ( clobs != null ) {
411
+ clobs .forEach ( clob -> {
412
+ try {
413
+ clob .free ();
414
+ }
415
+ catch (SQLException e ) {
416
+ log .debugf ( "Unable to free JDBC Clob reference [%s]" , e .getMessage () );
417
+ }
418
+ } );
419
+ clobs = null ;
420
+ }
421
+
422
+ if ( nclobs != null ) {
423
+ nclobs .forEach ( nclob -> {
424
+ try {
425
+ nclob .free ();
426
+ }
427
+ catch (SQLException e ) {
428
+ log .debugf ( "Unable to free JDBC NClob reference [%s]" , e .getMessage () );
429
+ }
430
+ } );
431
+ nclobs = null ;
432
+ }
433
+ }
434
+ }
386
435
}
0 commit comments