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