@@ -50,12 +50,8 @@ public final class ResourceRegistryStandardImpl implements ResourceRegistry {
5050 private final JdbcEventHandler jdbcEventHandler ;
5151
5252 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 ;
5853
54+ private ExtendedState ext ;
5955 private Statement lastQuery ;
6056
6157 public ResourceRegistryStandardImpl () {
@@ -69,10 +65,7 @@ public ResourceRegistryStandardImpl(JdbcEventHandler jdbcEventHandler) {
6965 @ Override
7066 public boolean hasRegisteredResources () {
7167 return hasRegistered ( xref )
72- || hasRegistered ( unassociatedResultSets )
73- || hasRegistered ( blobs )
74- || hasRegistered ( clobs )
75- || hasRegistered ( nclobs );
68+ || ext != null && ext .hasRegisteredResources ();
7669 }
7770
7871 @ Override
@@ -142,9 +135,8 @@ public void release(ResultSet resultSet, Statement statement) {
142135 }
143136 }
144137 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 );
148140 }
149141 }
150142 close ( resultSet );
@@ -241,11 +233,15 @@ public void register(ResultSet resultSet, Statement statement) {
241233 resultSets .put ( resultSet , PRESENT );
242234 }
243235 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 ();
248243 }
244+ return this .ext ;
249245 }
250246
251247 private JDBCException convert (SQLException e , String s ) {
@@ -254,56 +250,46 @@ private JDBCException convert(SQLException e, String s) {
254250
255251 @ Override
256252 public void register (Blob blob ) {
257- if ( blobs == null ) {
258- blobs = new ArrayList <>();
259- }
260-
261- blobs .add ( blob );
253+ getExtendedStateForWrite ().registerBlob ( blob );
262254 }
263255
264256 @ 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 ) {
267259 log .debug ( "Request to release Blob, but appears no Blobs have ever been registered" );
268260 return ;
269261 }
270- blobs .remove ( blob );
262+ ext . blobs .remove ( blob );
271263 }
272264
273265 @ 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 );
279268 }
280269
281270 @ 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 ) {
284273 log .debug ( "Request to release Clob, but appears no Clobs have ever been registered" );
285274 return ;
286275 }
287- clobs .remove ( clob );
276+ ext . clobs .remove ( clob );
288277 }
289278
290279 @ Override
291- public void register (NClob nclob ) {
280+ public void register (final NClob nclob ) {
292281 // todo : just store them in clobs?
293- if ( nclobs == null ) {
294- nclobs = new ArrayList <>();
295- }
296- nclobs .add ( nclob );
282+ getExtendedStateForWrite ().registerNClob ( nclob );
297283 }
298284
299285 @ Override
300286 public void release (NClob nclob ) {
301287 // todo : just store them in clobs?
302- if ( nclobs == null ) {
288+ if ( ext == null || ext . nclobs == null ) {
303289 log .debug ( "Request to release NClob, but appears no NClobs have ever been registered" );
304290 return ;
305291 }
306- nclobs .remove ( nclob );
292+ ext . nclobs .remove ( nclob );
307293 }
308294
309295 @ Override
@@ -332,55 +318,118 @@ public void releaseResources() {
332318 xref .forEach ( ResourceRegistryStandardImpl ::releaseXref );
333319 xref .clear ();
334320
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 ();
372323 }
373324
374325 if ( jdbcEventHandler != null ) {
375326 jdbcEventHandler .jdbcReleaseRegistryResourcesEnd ();
376327 }
377328 }
378329
379- private boolean hasRegistered (final HashMap resource ) {
330+ private static boolean hasRegistered (final HashMap resource ) {
380331 return resource != null && !resource .isEmpty ();
381332 }
382333
383- private boolean hasRegistered (final ArrayList resource ) {
334+ private static boolean hasRegistered (final ArrayList resource ) {
384335 return resource != null && !resource .isEmpty ();
385336 }
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+ }
386435}
0 commit comments