1111import java .sql .SQLException ;
1212import java .sql .Statement ;
1313import java .util .ArrayList ;
14- import java .util .HashMap ;
1514
16- import org .hibernate .HibernateException ;
1715import org .hibernate .JDBCException ;
1816import org .hibernate .internal .CoreLogging ;
1917import org .hibernate .internal .CoreMessageLogger ;
@@ -40,17 +38,9 @@ public final class ResourceRegistryStandardImpl implements ResourceRegistry {
4038 private static final CoreMessageLogger log = CoreLogging .messageLogger ( ResourceRegistryStandardImpl .class );
4139 private static final boolean IS_TRACE_ENABLED = log .isTraceEnabled ();
4240
43- // Dummy value to associate with an Object in the backing Map when we use it as a set:
44- private static final Object PRESENT = new Object ();
45-
46- //Used instead of Collections.EMPTY_SET to avoid polymorphic calls on xref;
47- //Also, uses an HashMap as it were an HashSet, as technically we just need the Set semantics
48- //but in this case the overhead of HashSet is not negligible.
49- private static final HashMap <ResultSet ,Object > EMPTY = new HashMap <>( 1 , 0.2f );
50-
5141 private final JdbcEventHandler jdbcEventHandler ;
5242
53- private final HashMap < Statement , HashMap < ResultSet , Object >> xref = new HashMap <> ();
43+ private final ResultsetsTrackingContainer xref = new ResultsetsTrackingContainer ();
5444
5545 private ExtendedState ext ;
5646 private Statement lastQuery ;
@@ -65,18 +55,15 @@ public ResourceRegistryStandardImpl(JdbcEventHandler jdbcEventHandler) {
6555
6656 @ Override
6757 public boolean hasRegisteredResources () {
68- return hasRegistered ( xref )
58+ return xref . hasRegisteredResources ( )
6959 || ext != null && ext .hasRegisteredResources ();
7060 }
7161
7262 @ Override
7363 public void register (Statement statement , boolean cancelable ) {
7464 if ( IS_TRACE_ENABLED ) log .tracef ( "Registering statement [%s]" , statement );
7565
76- HashMap <ResultSet ,Object > previousValue = xref .putIfAbsent ( statement , EMPTY );
77- if ( previousValue != null ) {
78- throw new HibernateException ( "JDBC Statement already registered" );
79- }
66+ xref .registerExpectingNew ( statement );
8067
8168 if ( cancelable ) {
8269 lastQuery = statement ;
@@ -87,7 +74,7 @@ public void register(Statement statement, boolean cancelable) {
8774 public void release (Statement statement ) {
8875 if ( IS_TRACE_ENABLED ) log .tracev ( "Releasing statement [{0}]" , statement );
8976
90- final HashMap < ResultSet , Object > resultSets = xref .remove ( statement );
77+ final ResultSetsSet resultSets = xref .remove ( statement );
9178 if ( resultSets != null ) {
9279 closeAll ( resultSets );
9380 }
@@ -117,12 +104,12 @@ public void release(ResultSet resultSet, Statement statement) {
117104 }
118105 }
119106 if ( statement != null ) {
120- final HashMap < ResultSet , Object > resultSets = xref .get ( statement );
107+ final ResultSetsSet resultSets = xref .getForResultSetRemoval ( statement );
121108 if ( resultSets == null ) {
122109 log .unregisteredStatement ();
123110 }
124111 else {
125- resultSets .remove ( resultSet );
112+ resultSets .removeResultSet ( resultSet );
126113 if ( resultSets .isEmpty () ) {
127114 try {
128115 if ( statement .isClosed () ) {
@@ -143,15 +130,14 @@ public void release(ResultSet resultSet, Statement statement) {
143130 close ( resultSet );
144131 }
145132
146- private static void closeAll (final HashMap < ResultSet , Object > resultSets ) {
133+ private static void closeAll (final ResultSetsSet resultSets ) {
147134 if ( resultSets == null ) {
148135 return ;
149136 }
150- resultSets .forEach ( (resultSet , o ) -> close ( resultSet ) );
151- resultSets .clear ();
137+ resultSets .forEachResultSet ( ResourceRegistryStandardImpl ::close );
152138 }
153139
154- private static void releaseXref (final Statement s , final HashMap < ResultSet , Object > r ) {
140+ private static void releaseXref (final Statement s , final ResultSetsSet r ) {
155141 closeAll ( r );
156142 close ( s );
157143 }
@@ -219,19 +205,7 @@ public void register(ResultSet resultSet, Statement statement) {
219205 }
220206 }
221207 if ( statement != null ) {
222- HashMap <ResultSet ,Object > resultSets = xref .get ( statement );
223-
224- // Keep this at DEBUG level, rather than warn. Numerous connection pool implementations can return a
225- // proxy/wrapper around the JDBC Statement, causing excessive logging here. See HHH-8210.
226- if ( resultSets == null ) {
227- log .debug ( "ResultSet statement was not registered (on register)" );
228- }
229-
230- if ( resultSets == null || resultSets == EMPTY ) {
231- resultSets = new HashMap <>();
232- xref .put ( statement , resultSets );
233- }
234- resultSets .put ( resultSet , PRESENT );
208+ xref .storeAssociatedResultset ( statement , resultSet );
235209 }
236210 else {
237211 getExtendedStateForWrite ().storeUnassociatedResultset ( resultSet );
@@ -328,7 +302,7 @@ public void releaseResources() {
328302 }
329303 }
330304
331- private static boolean hasRegistered (final HashMap resource ) {
305+ private static boolean hasRegistered (final ResultSetsSet resource ) {
332306 return resource != null && !resource .isEmpty ();
333307 }
334308
@@ -344,7 +318,7 @@ private static boolean hasRegistered(final ArrayList resource) {
344318 */
345319 private static class ExtendedState {
346320 //All fields lazily initialized as well:
347- private HashMap < ResultSet , Object > unassociatedResultSets ;
321+ private ResultSetsSet unassociatedResultSets ;
348322 private ArrayList <Blob > blobs ;
349323 private ArrayList <Clob > clobs ;
350324 private ArrayList <NClob > nclobs ;
@@ -357,17 +331,17 @@ public boolean hasRegisteredResources() {
357331 }
358332
359333 public void releaseUnassociatedResult (final ResultSet resultSet ) {
360- final Object removed = unassociatedResultSets == null ? null : unassociatedResultSets .remove ( resultSet );
334+ final Object removed = unassociatedResultSets == null ? null : unassociatedResultSets .removeResultSet ( resultSet );
361335 if ( removed == null ) {
362336 log .unregisteredResultSetWithoutStatement ();
363337 }
364338 }
365339
366340 public void storeUnassociatedResultset (ResultSet resultSet ) {
367341 if ( unassociatedResultSets == null ) {
368- this .unassociatedResultSets = new HashMap <> ();
342+ this .unassociatedResultSets = new ResultSetsSet ();
369343 }
370- unassociatedResultSets .put ( resultSet , PRESENT );
344+ unassociatedResultSets .storeResultSet ( resultSet );
371345 }
372346
373347 public void registerBlob (final Blob blob ) {
@@ -394,6 +368,7 @@ public void registerNClob(final NClob nclob) {
394368
395369 public void releaseResources () {
396370 closeAll ( unassociatedResultSets );
371+ unassociatedResultSets .clear ();
397372
398373 if ( blobs != null ) {
399374 blobs .forEach ( blob -> {
0 commit comments