8
8
import com .fasterxml .jackson .core .JsonGenerator ;
9
9
import com .fasterxml .jackson .core .JsonParser ;
10
10
import oracle .jdbc .OracleType ;
11
+ import oracle .jdbc .driver .DatabaseError ;
11
12
import oracle .sql .json .OracleJsonDatum ;
12
13
import oracle .sql .json .OracleJsonFactory ;
13
14
import oracle .sql .json .OracleJsonGenerator ;
14
15
import oracle .sql .json .OracleJsonParser ;
16
+ import org .hibernate .internal .CoreLogging ;
17
+ import org .hibernate .internal .CoreMessageLogger ;
15
18
import org .hibernate .metamodel .mapping .EmbeddableMappingType ;
16
19
import org .hibernate .metamodel .spi .RuntimeModelCreationContext ;
17
20
import org .hibernate .type .descriptor .ValueBinder ;
22
25
import org .hibernate .type .descriptor .jdbc .BasicBinder ;
23
26
import org .hibernate .type .descriptor .jdbc .BasicExtractor ;
24
27
import org .hibernate .type .format .FormatMapper ;
28
+ import org .hibernate .type .format .OsonDocumentReader ;
25
29
import org .hibernate .type .format .OsonDocumentWriter ;
26
30
import org .hibernate .type .format .jackson .JacksonOsonFormatMapper ;
27
31
32
+ import java .io .ByteArrayInputStream ;
28
33
import java .io .ByteArrayOutputStream ;
29
34
import java .io .InputStream ;
30
35
import java .sql .CallableStatement ;
43
48
public class OracleOsonJacksonJdbcType extends OracleJsonJdbcType {
44
49
public static final OracleOsonJacksonJdbcType INSTANCE = new OracleOsonJacksonJdbcType ( null );
45
50
46
- private static final Class osonFactoryKlass ;
51
+ private static final CoreMessageLogger LOG = CoreLogging .messageLogger ( OracleOsonJacksonJdbcType .class );
52
+
53
+ private static final Object osonFactory ;
47
54
static {
48
55
try {
49
- osonFactoryKlass = JacksonOsonFormatMapper .class .getClassLoader ().loadClass ( "oracle.jdbc.provider.oson.OsonFactory" );
56
+ Class osonFactoryKlass = JacksonOsonFormatMapper .class .getClassLoader ().loadClass ( "oracle.jdbc.provider.oson.OsonFactory" );
57
+ osonFactory = osonFactoryKlass .getDeclaredConstructor ().newInstance ();
50
58
}
51
- catch (ClassNotFoundException | LinkageError e ) {
59
+ catch (Exception | LinkageError e ) {
52
60
// should not happen as OracleOsonJacksonJdbcType is loaded
53
61
// only when Oracle OSON JDBC extension is present
54
62
// see OracleDialect class.
@@ -98,8 +106,7 @@ private <X> byte[] toOson(X value, JavaType<X> javaType, WrapperOptions options)
98
106
}
99
107
100
108
ByteArrayOutputStream out = new ByteArrayOutputStream ();
101
- JsonFactory osonFactory = (JsonFactory ) osonFactoryKlass .getDeclaredConstructor ().newInstance ();
102
- try (JsonGenerator osonGen = osonFactory .createGenerator ( out )) {
109
+ try (JsonGenerator osonGen = ((JsonFactory )osonFactory ).createGenerator ( out )) {
103
110
mapper .writeToTarget ( value , javaType , osonGen , options );
104
111
}
105
112
return out .toByteArray ();
@@ -151,7 +158,7 @@ private X fromOson(InputStream osonBytes, WrapperOptions options) throws Excepti
151
158
OracleJsonParser osonParser = new OracleJsonFactory ().createJsonBinaryParser ( osonBytes );
152
159
Object [] objects = JsonHelper .deserialize (
153
160
getEmbeddableMappingType (),
154
- osonParser ,
161
+ new OsonDocumentReader ( osonParser ) ,
155
162
javaType .getJavaTypeClass () != Object [].class ,
156
163
options
157
164
);
@@ -164,12 +171,23 @@ private X fromOson(InputStream osonBytes, WrapperOptions options) throws Excepti
164
171
type = (JavaType <X >) getEmbeddableMappingType ().getJavaType ();
165
172
}
166
173
167
- JsonFactory osonFactory = (JsonFactory ) osonFactoryKlass .getDeclaredConstructor ().newInstance ();
168
- try (JsonParser osonParser = osonFactory .createParser ( osonBytes )) {
174
+ try (JsonParser osonParser = ((JsonFactory )osonFactory ).createParser ( osonBytes )) {
169
175
return mapper .readFromSource ( type , osonParser , options );
170
176
}
171
177
}
172
178
179
+ private X doExtraction (byte [] bytes , WrapperOptions options ) throws SQLException {
180
+ if ( bytes == null ) {
181
+ return null ;
182
+ }
183
+
184
+ try {
185
+ return fromOson ( new ByteArrayInputStream (bytes ) ,options );
186
+ }
187
+ catch (Exception e ) {
188
+ throw new SQLException ( e );
189
+ }
190
+ }
173
191
private X doExtraction (OracleJsonDatum datum , WrapperOptions options ) throws SQLException {
174
192
if ( datum == null ) {
175
193
return null ;
@@ -185,22 +203,55 @@ private X doExtraction(OracleJsonDatum datum, WrapperOptions options) throws SQ
185
203
186
204
@ Override
187
205
protected X doExtract (ResultSet rs , int paramIndex , WrapperOptions options ) throws SQLException {
188
- OracleJsonDatum ojd = rs .getObject ( paramIndex , OracleJsonDatum .class );
189
- return doExtraction (ojd ,options );
190
-
206
+ try {
207
+ OracleJsonDatum ojd = rs .getObject ( paramIndex , OracleJsonDatum .class );
208
+ return doExtraction (ojd ,options );
209
+ } catch (SQLException exc ) {
210
+ if ( exc .getErrorCode () == DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
211
+ // this may happen if we are fetching data from an existing schema
212
+ // that use CBLOB for JSON column
213
+ LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
214
+ return doExtraction (rs .getBytes ( paramIndex ), options );
215
+ } else {
216
+ throw exc ;
217
+ }
218
+ }
191
219
}
192
220
193
221
@ Override
194
222
protected X doExtract (CallableStatement statement , int index , WrapperOptions options ) throws SQLException {
195
- OracleJsonDatum ojd = statement .getObject ( index , OracleJsonDatum .class );
196
- return doExtraction (ojd ,options );
223
+ try {
224
+ OracleJsonDatum ojd = statement .getObject ( index , OracleJsonDatum .class );
225
+ return doExtraction (ojd ,options );
226
+ } catch (SQLException exc ) {
227
+ if ( exc .getErrorCode () == DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
228
+ // this may happen if we are fetching data from an existing schema
229
+ // that use CBLOB for JSON column
230
+ LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
231
+ return doExtraction (statement .getBytes ( index ), options );
232
+ } else {
233
+ throw exc ;
234
+ }
235
+ }
197
236
}
198
237
199
238
@ Override
200
239
protected X doExtract (CallableStatement statement , String name , WrapperOptions options )
201
240
throws SQLException {
202
- OracleJsonDatum ojd = statement .getObject ( name , OracleJsonDatum .class );
203
- return doExtraction (ojd ,options );
241
+ try {
242
+ OracleJsonDatum ojd = statement .getObject ( name , OracleJsonDatum .class );
243
+ return doExtraction (ojd ,options );
244
+ } catch (SQLException exc ) {
245
+ if ( exc .getErrorCode () == DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
246
+ // this may happen if we are fetching data from an existing schema
247
+ // that use CBLOB for JSON column
248
+ LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
249
+ return doExtraction (statement .getBytes ( name ), options );
250
+ } else {
251
+ throw exc ;
252
+ }
253
+ }
254
+
204
255
}
205
256
206
257
};
0 commit comments