Skip to content

Commit a6eff35

Browse files
committed
Introduce a separate ExtendedState holder for ResourceRegistryStandardImpl
1 parent 01e8f02 commit a6eff35

File tree

1 file changed

+127
-78
lines changed

1 file changed

+127
-78
lines changed

hibernate-core/src/main/java/org/hibernate/resource/jdbc/internal/ResourceRegistryStandardImpl.java

Lines changed: 127 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)