77import  java .sql .ResultSetMetaData ;
88import  java .sql .SQLException ;
99
10+ import  jakarta .persistence .EnumType ;
1011import  org .hibernate .dialect .Dialect ;
12+ import  org .hibernate .engine .jdbc .spi .SqlExceptionHelper ;
13+ import  org .hibernate .engine .spi .SessionFactoryImplementor ;
1114import  org .hibernate .engine .spi .SharedSessionContractImplementor ;
1215import  org .hibernate .internal .util .StringHelper ;
16+ import  org .hibernate .type .BasicType ;
17+ import  org .hibernate .type .descriptor .java .JavaType ;
18+ import  org .hibernate .type .descriptor .jdbc .JdbcType ;
19+ import  org .hibernate .type .descriptor .jdbc .JdbcTypeIndicators ;
20+ import  org .hibernate .type .descriptor .jdbc .spi .JdbcTypeRegistry ;
21+ import  org .hibernate .type .spi .TypeConfiguration ;
1322
1423/** 
24+  * Base implementation of {@link ResultSetAccess}. 
25+  * 
1526 * @author Steve Ebersole 
1627 */ 
1728public  abstract  class  AbstractResultSetAccess  implements  ResultSetAccess  {
1829	private  final  SharedSessionContractImplementor  persistenceContext ;
19- 	private  final  Dialect  dialect ;
2030	private  ResultSetMetaData  resultSetMetaData ;
2131
2232	public  AbstractResultSetAccess (SharedSessionContractImplementor  persistenceContext ) {
2333		this .persistenceContext  = persistenceContext ;
24- 		this .dialect  = persistenceContext .getJdbcServices ().getDialect ();
2534	}
2635
36+ 	protected  abstract  SessionFactoryImplementor  getFactory ();
37+ 
2738	protected  SharedSessionContractImplementor  getPersistenceContext () {
2839		return  persistenceContext ;
2940	}
3041
31- 	protected  ResultSetMetaData  getMetaData () {
42+ 	private  SqlExceptionHelper  getSqlExceptionHelper () {
43+ 		return  getFactory ().getJdbcServices ().getSqlExceptionHelper ();
44+ 	}
45+ 
46+ 	private  Dialect  getDialect () {
47+ 		return  getFactory ().getJdbcServices ().getDialect ();
48+ 	}
49+ 
50+ 	private  ResultSetMetaData  getResultSetMetaData () {
3251		if  ( resultSetMetaData  == null  ) {
3352			try  {
3453				resultSetMetaData  = getResultSet ().getMetaData ();
3554			}
3655			catch  (SQLException  e ) {
37- 				throw  persistenceContext . getJdbcServices (). getSqlExceptionHelper ()
56+ 				throw  getSqlExceptionHelper ()
3857						.convert ( e , "Unable to access ResultSetMetaData"  );
3958			}
4059		}
@@ -45,37 +64,111 @@ protected ResultSetMetaData getMetaData() {
4564	@ Override 
4665	public  int  getColumnCount () {
4766		try  {
48- 			return  getMetaData ().getColumnCount ();
67+ 			return  getResultSetMetaData ().getColumnCount ();
4968		}
5069		catch  (SQLException  e ) {
51- 			throw  getFactory (). getJdbcServices (). getJdbcEnvironment (). getSqlExceptionHelper ()
70+ 			throw  getSqlExceptionHelper ()
5271					.convert ( e , "Unable to access ResultSet column count"  );
5372		}
5473	}
5574
5675	@ Override 
5776	public  int  resolveColumnPosition (String  columnName ) {
5877		try  {
59- 			return  getResultSet ().findColumn (
60- 					StringHelper .unquote ( columnName , this .dialect  )
61- 			);
78+ 			return  getResultSet ()
79+ 					.findColumn ( StringHelper .unquote ( columnName , getDialect () ) );
6280		}
6381		catch  (SQLException  e ) {
64- 			throw  getFactory (). getJdbcServices (). getJdbcEnvironment (). getSqlExceptionHelper ()
82+ 			throw  getSqlExceptionHelper ()
6583					.convert ( e , "Unable to find column position by name: "  + columnName  );
6684		}
6785	}
6886
6987	@ Override 
7088	public  String  resolveColumnName (int  position ) {
7189		try  {
72- 			return  dialect 
73- 					.getColumnAliasExtractor ()
74- 					.extractColumnAlias ( getMetaData (), position  );
90+ 			return  getDialect ().getColumnAliasExtractor ()
91+ 					.extractColumnAlias ( getResultSetMetaData (), position  );
7592		}
7693		catch  (SQLException  e ) {
77- 			throw  getFactory (). getJdbcServices (). getJdbcEnvironment (). getSqlExceptionHelper ()
94+ 			throw  getSqlExceptionHelper ()
7895					.convert ( e , "Unable to find column name by position"  );
7996		}
8097	}
98+ 
99+ 	@ Override 
100+ 	public  int  getResultCountEstimate () {
101+ 		return  -1 ;
102+ 	}
103+ 
104+ 	@ Override 
105+ 	public  <J > BasicType <J > resolveType (int  position , JavaType <J > explicitJavaType , TypeConfiguration  typeConfiguration ) {
106+ 		try  {
107+ 			final  ResultSetMetaData  metaData  = getResultSetMetaData ();
108+ 			final  JdbcTypeRegistry  registry  = typeConfiguration .getJdbcTypeRegistry ();
109+ 			final  String  columnTypeName  = metaData .getColumnTypeName ( position  );
110+ 			final  int  columnType  = metaData .getColumnType ( position  );
111+ 			final  int  scale  = metaData .getScale ( position  );
112+ 			final  int  precision  = metaData .getPrecision ( position  );
113+ 			final  int  displaySize  = metaData .getColumnDisplaySize ( position  );
114+ 			final  Dialect  dialect  = getDialect ();
115+ 			final  int  length  = dialect .resolveSqlTypeLength ( columnTypeName , columnType , precision , scale , displaySize  );
116+ 			final  JdbcType  resolvedJdbcType  =
117+ 					dialect .resolveSqlTypeDescriptor ( columnTypeName , columnType , length , scale , registry  );
118+ 			final  JdbcType  jdbcType  =
119+ 					explicitJavaType  == null 
120+ 							? resolvedJdbcType 
121+ 							: jdbcType ( explicitJavaType , resolvedJdbcType , length , precision , scale , typeConfiguration  );
122+ 			// If there is an explicit JavaType, then prefer its recommended JDBC type 
123+ 			final  JavaType <J > javaType  =
124+ 					explicitJavaType  == null 
125+ 							? jdbcType .getJdbcRecommendedJavaTypeMapping ( length , scale , typeConfiguration  )
126+ 							: explicitJavaType ;
127+ 			return  typeConfiguration .getBasicTypeRegistry ().resolve ( javaType , jdbcType  );
128+ 		}
129+ 		catch  (SQLException  e ) {
130+ 			throw  getSqlExceptionHelper ()
131+ 					.convert ( e , "Unable to determine JDBC type code for ResultSet position "  + position  );
132+ 		}
133+ 	}
134+ 
135+ 	private  <J > JdbcType  jdbcType (
136+ 			JavaType <J > javaType ,
137+ 			JdbcType  resolvedJdbcType ,
138+ 			int  length , int  precision , int  scale ,
139+ 			TypeConfiguration  typeConfiguration ) {
140+ 		return  javaType .getRecommendedJdbcType (
141+ 				new  JdbcTypeIndicators () {
142+ 					@ Override 
143+ 					public  TypeConfiguration  getTypeConfiguration () {
144+ 						return  typeConfiguration ;
145+ 					}
146+ 
147+ 					@ Override 
148+ 					public  long  getColumnLength () {
149+ 						return  length ;
150+ 					}
151+ 
152+ 					@ Override 
153+ 					public  int  getColumnPrecision () {
154+ 						return  precision ;
155+ 					}
156+ 
157+ 					@ Override 
158+ 					public  int  getColumnScale () {
159+ 						return  scale ;
160+ 					}
161+ 
162+ 					@ Override 
163+ 					public  EnumType  getEnumeratedType () {
164+ 						return  resolvedJdbcType .isNumber () ? EnumType .ORDINAL  : EnumType .STRING ;
165+ 					}
166+ 
167+ 					@ Override 
168+ 					public  Dialect  getDialect () {
169+ 						return  AbstractResultSetAccess .this .getDialect ();
170+ 					}
171+ 				}
172+ 		);
173+ 	}
81174}
0 commit comments