4
4
*/
5
5
package org .hibernate .dialect ;
6
6
7
- import com .fasterxml .jackson .core .JsonParser ;
8
7
import oracle .jdbc .OracleType ;
9
8
import oracle .jdbc .driver .DatabaseError ;
10
9
import oracle .sql .json .OracleJsonDatum ;
28
27
import org .hibernate .type .format .OsonDocumentWriter ;
29
28
30
29
import java .io .ByteArrayOutputStream ;
30
+ import java .io .Closeable ;
31
31
import java .io .InputStream ;
32
32
import java .nio .charset .StandardCharsets ;
33
33
import java .sql .CallableStatement ;
34
34
import java .sql .PreparedStatement ;
35
35
import java .sql .ResultSet ;
36
36
import java .sql .SQLException ;
37
37
38
- import static org .hibernate .dialect .OracleOsonJacksonJdbcType .OSON_JACKSON_FACTORY ;
39
- import static org .hibernate .dialect .OracleOsonJacksonJdbcType .OSON_JSON_FACTORY ;
38
+ import static org .hibernate .dialect .OracleOsonJdbcType .OSON_JSON_FACTORY ;
40
39
41
40
/**
42
41
*
47
46
* @author Emmanuel Jannetti
48
47
* @author Bidyadhar Mohanty
49
48
*/
50
- public class OracleOsonJacksonArrayJdbcType extends OracleJsonArrayJdbcType {
49
+ public class OracleOsonArrayJdbcType extends OracleJsonArrayJdbcType {
51
50
52
- private static final CoreMessageLogger LOG = CoreLogging .messageLogger ( OracleOsonJacksonArrayJdbcType .class );
51
+ private static final CoreMessageLogger LOG = CoreLogging .messageLogger ( OracleOsonArrayJdbcType .class );
53
52
54
- public OracleOsonJacksonArrayJdbcType (JdbcType elementJdbcType ) {
53
+ public OracleOsonArrayJdbcType (JdbcType elementJdbcType ) {
55
54
super (elementJdbcType );
56
55
}
57
56
58
-
59
57
@ Override
60
58
public String toString () {
61
- return "OracleOsonJacksonArrayJdbcType " ;
59
+ return "OracleOsonArrayJdbcType " ;
62
60
}
63
61
64
-
65
62
@ Override
66
63
public <X > ValueBinder <X > getBinder (JavaType <X > javaType ) {
67
64
@@ -73,7 +70,9 @@ private <T> byte[] toOsonStream(T value, JavaType<T> javaType, WrapperOptions op
73
70
try (OracleJsonGenerator generator = OSON_JSON_FACTORY .createJsonBinaryGenerator ( out )) {
74
71
final JavaType <?> elementJavaType = ((BasicPluralJavaType <?>) javaType ).getElementJavaType ();
75
72
if ( elementJavaType instanceof UnknownBasicJavaType <?> ) {
76
- options .getJsonFormatMapper ().writeToTarget ( value , javaType , generator , options );
73
+ try (Closeable osonGen = OracleOsonJacksonHelper .createWriteTarget ( out )) {
74
+ options .getJsonFormatMapper ().writeToTarget ( value , javaType , osonGen , options );
75
+ }
77
76
}
78
77
else {
79
78
final OsonDocumentWriter writer = new OsonDocumentWriter ( generator );
@@ -92,15 +91,31 @@ private <T> byte[] toOsonStream(T value, JavaType<T> javaType, WrapperOptions op
92
91
);
93
92
}
94
93
}
95
- return out .toByteArray ();
96
94
}
95
+ return out .toByteArray ();
96
+ }
97
97
98
+ private boolean useUtf8 (WrapperOptions options ) {
99
+ final JavaType <?> elementJavaType = ((BasicPluralJavaType <?>) getJavaType ()).getElementJavaType ();
100
+ return elementJavaType instanceof UnknownBasicJavaType <?>
101
+ && !options .getJsonFormatMapper ().supportsTargetType ( OracleOsonJacksonHelper .WRITER_CLASS );
98
102
}
103
+
99
104
@ Override
100
105
protected void doBind (PreparedStatement st , X value , int index , WrapperOptions options )
101
106
throws SQLException {
102
107
try {
103
- st .setObject ( index , toOsonStream ( value , getJavaType (), options ), OracleType .JSON );
108
+ if ( useUtf8 ( options ) ) {
109
+ final String json = OracleOsonArrayJdbcType .this .toString (
110
+ value ,
111
+ getJavaType (),
112
+ options
113
+ );
114
+ st .setBytes ( index , json .getBytes ( StandardCharsets .UTF_8 ) );
115
+ }
116
+ else {
117
+ st .setObject ( index , toOsonStream ( value , getJavaType (), options ), OracleType .JSON );
118
+ }
104
119
}
105
120
catch (Exception e ) {
106
121
throw new SQLException ( e );
@@ -111,7 +126,17 @@ protected void doBind(PreparedStatement st, X value, int index, WrapperOptions o
111
126
protected void doBind (CallableStatement st , X value , String name , WrapperOptions options )
112
127
throws SQLException {
113
128
try {
114
- st .setObject ( name , toOsonStream ( value , getJavaType (), options ) , OracleType .JSON );
129
+ if ( useUtf8 ( options ) ) {
130
+ final String json = OracleOsonArrayJdbcType .this .toString (
131
+ value ,
132
+ getJavaType (),
133
+ options
134
+ );
135
+ st .setBytes ( name , json .getBytes ( StandardCharsets .UTF_8 ) );
136
+ }
137
+ else {
138
+ st .setObject ( name , toOsonStream ( value , getJavaType (), options ), OracleType .JSON );
139
+ }
115
140
}
116
141
catch (Exception e ) {
117
142
throw new SQLException ( e );
@@ -127,7 +152,7 @@ public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
127
152
128
153
private X fromOson (InputStream osonBytes , WrapperOptions options ) throws Exception {
129
154
if ( ((BasicPluralJavaType <?>) getJavaType ()).getElementJavaType () instanceof UnknownBasicJavaType <?> ) {
130
- try (JsonParser oParser = OSON_JACKSON_FACTORY . createParser ( osonBytes )) {
155
+ try (Closeable oParser = OracleOsonJacksonHelper . createReadSource ( osonBytes )) {
131
156
return options .getJsonFormatMapper ().readFromSource ( getJavaType (), oParser , options );
132
157
}
133
158
}
@@ -155,21 +180,40 @@ private X doExtraction(OracleJsonDatum datum, WrapperOptions options) throws SQ
155
180
}
156
181
}
157
182
183
+ private boolean useUtf8 (WrapperOptions options ) {
184
+ final JavaType <?> elementJavaType = ((BasicPluralJavaType <?>) getJavaType ()).getElementJavaType ();
185
+ return elementJavaType instanceof UnknownBasicJavaType <?>
186
+ && !options .getJsonFormatMapper ().supportsTargetType ( OracleOsonJacksonHelper .READER_CLASS );
187
+ }
188
+
189
+ private X fromString (byte [] json , WrapperOptions options ) throws SQLException {
190
+ if ( json == null ) {
191
+ return null ;
192
+ }
193
+ return OracleOsonArrayJdbcType .this .fromString (
194
+ new String ( json , StandardCharsets .UTF_8 ),
195
+ getJavaType (),
196
+ options
197
+ );
198
+ }
199
+
158
200
@ Override
159
201
protected X doExtract (ResultSet rs , int paramIndex , WrapperOptions options ) throws SQLException {
160
202
try {
161
- OracleJsonDatum ojd = rs .getObject ( paramIndex , OracleJsonDatum .class );
162
- return doExtraction ( ojd , options );
203
+ if ( useUtf8 ( options ) ) {
204
+ return fromString ( rs .getBytes ( paramIndex ), options );
205
+ }
206
+ else {
207
+ OracleJsonDatum ojd = rs .getObject ( paramIndex , OracleJsonDatum .class );
208
+ return doExtraction ( ojd , options );
209
+ }
163
210
} catch (SQLException exc ) {
164
211
if ( exc .getErrorCode () == DatabaseError .JDBC_ERROR_BASE + DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
165
212
// This may happen if we are fetching data from an existing schema
166
213
// that uses BLOB for JSON column In that case we assume bytes are
167
214
// UTF-8 bytes (i.e not OSON) and we fall back to previous String-based implementation
168
215
LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
169
- return OracleOsonJacksonArrayJdbcType .this .fromString (
170
- new String ( rs .getBytes ( paramIndex ), StandardCharsets .UTF_8 ),
171
- getJavaType (),
172
- options );
216
+ return fromString ( rs .getBytes ( paramIndex ), options );
173
217
} else {
174
218
throw exc ;
175
219
}
@@ -179,18 +223,20 @@ protected X doExtract(ResultSet rs, int paramIndex, WrapperOptions options) thro
179
223
@ Override
180
224
protected X doExtract (CallableStatement statement , int index , WrapperOptions options ) throws SQLException {
181
225
try {
182
- OracleJsonDatum ojd = statement .getObject ( index , OracleJsonDatum .class );
183
- return doExtraction ( ojd , options );
226
+ if ( useUtf8 ( options ) ) {
227
+ return fromString ( statement .getBytes ( index ), options );
228
+ }
229
+ else {
230
+ OracleJsonDatum ojd = statement .getObject ( index , OracleJsonDatum .class );
231
+ return doExtraction ( ojd , options );
232
+ }
184
233
} catch (SQLException exc ) {
185
234
if ( exc .getErrorCode () == DatabaseError .JDBC_ERROR_BASE + DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
186
235
// This may happen if we are fetching data from an existing schema
187
236
// that uses BLOB for JSON column In that case we assume bytes are
188
237
// UTF-8 bytes (i.e not OSON) and we fall back to previous String-based implementation
189
238
LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
190
- return OracleOsonJacksonArrayJdbcType .this .fromString (
191
- new String ( statement .getBytes ( index ), StandardCharsets .UTF_8 ),
192
- getJavaType (),
193
- options );
239
+ return fromString ( statement .getBytes ( index ), options );
194
240
} else {
195
241
throw exc ;
196
242
}
@@ -201,18 +247,20 @@ protected X doExtract(CallableStatement statement, int index, WrapperOptions opt
201
247
protected X doExtract (CallableStatement statement , String name , WrapperOptions options )
202
248
throws SQLException {
203
249
try {
204
- OracleJsonDatum ojd = statement .getObject ( name , OracleJsonDatum .class );
205
- return doExtraction ( ojd , options );
250
+ if ( useUtf8 ( options ) ) {
251
+ return fromString ( statement .getBytes ( name ), options );
252
+ }
253
+ else {
254
+ OracleJsonDatum ojd = statement .getObject ( name , OracleJsonDatum .class );
255
+ return doExtraction ( ojd , options );
256
+ }
206
257
} catch (SQLException exc ) {
207
258
if ( exc .getErrorCode () == DatabaseError .JDBC_ERROR_BASE + DatabaseError .EOJ_INVALID_COLUMN_TYPE ) {
208
259
// This may happen if we are fetching data from an existing schema
209
260
// that uses BLOB for JSON column In that case we assume bytes are
210
261
// UTF-8 bytes (i.e not OSON) and we fall back to previous String-based implementation
211
262
LOG .invalidJSONColumnType ( OracleType .CLOB .getName (), OracleType .JSON .getName () );
212
- return OracleOsonJacksonArrayJdbcType .this .fromString (
213
- new String ( statement .getBytes ( name ), StandardCharsets .UTF_8 ),
214
- getJavaType (),
215
- options );
263
+ return fromString ( statement .getBytes ( name ), options );
216
264
} else {
217
265
throw exc ;
218
266
}
0 commit comments