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