66
77import  com .fasterxml .jackson .core .JsonParser ;
88import  oracle .jdbc .OracleType ;
9+ import  oracle .jdbc .driver .DatabaseError ;
910import  oracle .jdbc .provider .oson .OsonFactory ;
1011import  oracle .sql .json .OracleJsonDatum ;
1112import  oracle .sql .json .OracleJsonFactory ;
1213import  oracle .sql .json .OracleJsonGenerator ;
1314
15+ import  org .hibernate .internal .CoreLogging ;
16+ import  org .hibernate .internal .CoreMessageLogger ;
1417import  org .hibernate .metamodel .mapping .EmbeddableMappingType ;
1518import  org .hibernate .type .descriptor .ValueBinder ;
1619import  org .hibernate .type .descriptor .ValueExtractor ;
2730
2831import  java .io .ByteArrayOutputStream ;
2932import  java .io .InputStream ;
33+ import  java .nio .charset .StandardCharsets ;
3034import  java .sql .CallableStatement ;
3135import  java .sql .PreparedStatement ;
3236import  java .sql .ResultSet ;
4347 */ 
4448public  class  OracleOsonJacksonArrayJdbcType  extends  OracleJsonArrayJdbcType  {
4549
50+ 	private  static  final  CoreMessageLogger  LOG  = CoreLogging .messageLogger ( OracleOsonJacksonArrayJdbcType .class  );
4651
4752	private  static  final  OsonFactory  osonFactory  = new  OsonFactory ();
4853
@@ -121,6 +126,7 @@ public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
121126			private  X  fromOson (InputStream  osonBytes , WrapperOptions  options ) throws  Exception  {
122127				FormatMapper  mapper  = options .getJsonFormatMapper ();
123128				JsonParser  osonParser  = osonFactory .createParser ( osonBytes  );
129+ 
124130				return  mapper .readFromSource (  getJavaType (), osonParser , options );
125131			}
126132
@@ -139,25 +145,66 @@ private X doExtraction(OracleJsonDatum datum,  WrapperOptions options) throws SQ
139145
140146			@ Override 
141147			protected  X  doExtract (ResultSet  rs , int  paramIndex , WrapperOptions  options ) throws  SQLException  {
142- 
143- 				OracleJsonDatum  ojd  = rs .getObject ( paramIndex , OracleJsonDatum .class  );
144- 				return  doExtraction ( ojd , options );
148+ 				try  {
149+ 					OracleJsonDatum  ojd  = rs .getObject ( paramIndex , OracleJsonDatum .class  );
150+ 					return  doExtraction ( ojd , options );
151+ 				} catch  (SQLException  exc ) {
152+ 					if  ( exc .getErrorCode () == DatabaseError .JDBC_ERROR_BASE  + DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
153+ 						// This may happen if we are fetching data from an existing schema 
154+ 						// that uses BLOB for JSON column In that case we assume bytes are 
155+ 						// UTF-8 bytes (i.e not OSON) and we fall back to previous String-based implementation 
156+ 						LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
157+ 						return  OracleOsonJacksonArrayJdbcType .this .fromString (
158+ 								new  String ( rs .getBytes ( paramIndex  ), StandardCharsets .UTF_8  ),
159+ 								getJavaType (),
160+ 								options );
161+ 					} else  {
162+ 						throw  exc ;
163+ 					}
164+ 				}
145165			}
146166
147167			@ Override 
148168			protected  X  doExtract (CallableStatement  statement , int  index , WrapperOptions  options ) throws  SQLException  {
149- 
150- 
151- 				OracleJsonDatum  ojd  = statement .getObject ( index , OracleJsonDatum .class  );
152- 				return  doExtraction ( ojd , options );
169+ 				try  {
170+ 					OracleJsonDatum  ojd  = statement .getObject ( index , OracleJsonDatum .class  );
171+ 					return  doExtraction ( ojd , options );
172+ 				} catch  (SQLException  exc ) {
173+ 					if  ( exc .getErrorCode () == DatabaseError .JDBC_ERROR_BASE  + DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
174+ 						// This may happen if we are fetching data from an existing schema 
175+ 						// that uses BLOB for JSON column In that case we assume bytes are 
176+ 						// UTF-8 bytes (i.e not OSON) and we fall back to previous String-based implementation 
177+ 						LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
178+ 						return  OracleOsonJacksonArrayJdbcType .this .fromString (
179+ 								new  String ( statement .getBytes ( index  ), StandardCharsets .UTF_8  ),
180+ 								getJavaType (),
181+ 								options );
182+ 					} else  {
183+ 						throw  exc ;
184+ 					}
185+ 				}
153186			}
154187
155188			@ Override 
156189			protected  X  doExtract (CallableStatement  statement , String  name , WrapperOptions  options )
157190					throws  SQLException  {
158- 
159- 				OracleJsonDatum  ojd  = statement .getObject ( name , OracleJsonDatum .class  );
160- 				return  doExtraction ( ojd , options );
191+ 				try  {
192+ 					OracleJsonDatum  ojd  = statement .getObject ( name , OracleJsonDatum .class  );
193+ 					return  doExtraction ( ojd , options );
194+ 				} catch  (SQLException  exc ) {
195+ 					if  ( exc .getErrorCode () == DatabaseError .JDBC_ERROR_BASE  + DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
196+ 						// This may happen if we are fetching data from an existing schema 
197+ 						// that uses BLOB for JSON column In that case we assume bytes are 
198+ 						// UTF-8 bytes (i.e not OSON) and we fall back to previous String-based implementation 
199+ 						LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
200+ 						return  OracleOsonJacksonArrayJdbcType .this .fromString (
201+ 								new  String ( statement .getBytes ( name  ), StandardCharsets .UTF_8  ),
202+ 								getJavaType (),
203+ 								options );
204+ 					} else  {
205+ 						throw  exc ;
206+ 					}
207+ 				}
161208			}
162209		};
163210	}
0 commit comments