7
7
8
8
import java .lang .reflect .Array ;
9
9
import java .sql .CallableStatement ;
10
+ import java .sql .Date ;
10
11
import java .sql .PreparedStatement ;
11
12
import java .sql .ResultSet ;
12
13
import java .sql .SQLException ;
14
+ import java .sql .Time ;
15
+ import java .sql .Timestamp ;
13
16
import java .sql .Types ;
17
+ import java .time .LocalDate ;
18
+ import java .time .LocalDateTime ;
19
+ import java .time .LocalTime ;
14
20
15
- import org .hibernate .HibernateException ;
21
+ import org .hibernate .reactive .adaptor .impl .ArrayAdaptor ;
22
+ import org .hibernate .reactive .adaptor .impl .ResultSetAdaptor ;
16
23
import org .hibernate .type .descriptor .ValueBinder ;
17
24
import org .hibernate .type .descriptor .ValueExtractor ;
18
25
import org .hibernate .type .descriptor .WrapperOptions ;
24
31
import org .hibernate .type .descriptor .jdbc .BasicExtractor ;
25
32
import org .hibernate .type .descriptor .jdbc .JdbcLiteralFormatter ;
26
33
import org .hibernate .type .descriptor .jdbc .JdbcType ;
27
- import org .hibernate .type .descriptor .jdbc .ObjectJdbcType ;
28
34
import org .hibernate .type .descriptor .jdbc .internal .JdbcLiteralFormatterArray ;
29
35
import org .hibernate .type .spi .TypeConfiguration ;
30
36
37
+
38
+
31
39
/**
32
40
* {@link java.sql.Connection} has a method {@link java.sql.Connection#createArrayOf(String, Object[])}, but we don't have
33
41
* it in Vert.x SQL Client.
42
+ * <p>
43
+ * Plus, the Vert.x SQL client accept arrays as parameters.
44
+ * </p>
34
45
*
35
46
* @see org.hibernate.type.descriptor.jdbc.ArrayJdbcType
36
47
*/
37
- public class ReactiveArrayJdbcType implements JdbcType {
38
-
39
- public static final ReactiveArrayJdbcType INSTANCE = new ReactiveArrayJdbcType ( ObjectJdbcType .INSTANCE );
48
+ public class ReactiveArrayJdbcType implements JdbcType {
40
49
41
50
private final JdbcType elementJdbcType ;
42
51
@@ -88,20 +97,64 @@ public <X> ValueBinder<X> getBinder(final JavaType<X> javaTypeDescriptor) {
88
97
@ Override
89
98
protected void doBind (PreparedStatement st , X value , int index , WrapperOptions options )
90
99
throws SQLException {
91
- st .setObject ( index , value );
100
+
101
+ ArrayAdaptor arrayObject = getArrayObject ( value , options );
102
+ st .setArray ( index , arrayObject );
92
103
}
93
104
94
105
@ Override
95
- protected void doBind (CallableStatement st , X value , String name , WrapperOptions options ){
96
- try {
97
- st .setObject ( name , value );
106
+ protected void doBind (CallableStatement st , X value , String name , WrapperOptions options ) {
107
+ throw new UnsupportedOperationException ();
108
+ }
109
+
110
+ private ArrayAdaptor getArrayObject (X value , WrapperOptions options ) {
111
+ final TypeConfiguration typeConfiguration = options .getSessionFactory ().getTypeConfiguration ();
112
+ ReactiveArrayJdbcType jdbcType = (ReactiveArrayJdbcType ) getJdbcType ();
113
+ final JdbcType elementJdbcType = jdbcType .getElementJdbcType ();
114
+ final JdbcType underlyingJdbcType = typeConfiguration .getJdbcTypeRegistry ()
115
+ .getDescriptor ( elementJdbcType .getDefaultSqlTypeCode () );
116
+ final Class <?> elementJdbcJavaTypeClass = elementJdbcJavaTypeClass (
117
+ options ,
118
+ elementJdbcType ,
119
+ underlyingJdbcType ,
120
+ typeConfiguration
121
+ );
122
+ //noinspection unchecked
123
+ final Class <Object []> arrayClass = (Class <Object []>) Array .newInstance ( elementJdbcJavaTypeClass , 0 )
124
+ .getClass ();
125
+ final Object [] objects = getJavaType ().unwrap ( value , arrayClass , options );
126
+ return new ArrayAdaptor ( elementJdbcType , objects );
127
+ }
128
+
129
+ private Class <?> elementJdbcJavaTypeClass (
130
+ WrapperOptions options ,
131
+ JdbcType elementJdbcType ,
132
+ JdbcType underlyingJdbcType ,
133
+ TypeConfiguration typeConfiguration ) {
134
+ final Class <?> preferredJavaTypeClass = elementJdbcType .getPreferredJavaTypeClass ( options );
135
+ final Class <?> elementJdbcJavaTypeClass ;
136
+ if ( preferredJavaTypeClass == null ) {
137
+ elementJdbcJavaTypeClass = underlyingJdbcType
138
+ .getJdbcRecommendedJavaTypeMapping ( null , null , typeConfiguration )
139
+ .getJavaTypeClass ();
98
140
}
99
- catch (SQLException ex ) {
100
- throw new HibernateException (
101
- "JDBC driver does not support named parameters for setArray. Use positional." ,
102
- ex
103
- );
141
+ else {
142
+ elementJdbcJavaTypeClass = preferredJavaTypeClass ;
104
143
}
144
+ return convertTypes ( elementJdbcJavaTypeClass );
145
+ }
146
+
147
+ private Class <?> convertTypes (Class <?> elementJdbcJavaTypeClass ) {
148
+ if ( Timestamp .class .equals ( elementJdbcJavaTypeClass ) ) {
149
+ return LocalDateTime .class ;
150
+ }
151
+ if ( Date .class .equals ( elementJdbcJavaTypeClass ) ) {
152
+ return LocalDate .class ;
153
+ }
154
+ if ( Time .class .equals ( elementJdbcJavaTypeClass ) ) {
155
+ return LocalTime .class ;
156
+ }
157
+ return elementJdbcJavaTypeClass ;
105
158
}
106
159
};
107
160
}
@@ -110,13 +163,19 @@ protected void doBind(CallableStatement st, X value, String name, WrapperOptions
110
163
public <X > ValueExtractor <X > getExtractor (final JavaType <X > javaTypeDescriptor ) {
111
164
return new BasicExtractor <>( javaTypeDescriptor , this ) {
112
165
@ Override
113
- protected X doExtract (ResultSet rs , int paramIndex , WrapperOptions options ) throws SQLException {
114
- return javaTypeDescriptor .wrap ( rs .getArray ( paramIndex ), options );
166
+ protected X doExtract (ResultSet rs , int paramIndex , WrapperOptions options ) {
167
+ return javaTypeDescriptor .wrap (
168
+ ( (ResultSetAdaptor ) rs ).getArray ( paramIndex , elementJdbcType ),
169
+ options
170
+ );
115
171
}
116
172
117
173
@ Override
118
- protected X doExtract (CallableStatement statement , int index , WrapperOptions options ) throws SQLException {
119
- return javaTypeDescriptor .wrap ( statement .getArray ( index ), options );
174
+ protected X doExtract (CallableStatement statement , int index , WrapperOptions options ) {
175
+ return javaTypeDescriptor .wrap (
176
+ ( (ResultSetAdaptor ) statement ).getArray ( index , elementJdbcType ),
177
+ options
178
+ );
120
179
}
121
180
122
181
@ Override
@@ -132,6 +191,10 @@ public String getFriendlyName() {
132
191
return "ARRAY" ;
133
192
}
134
193
194
+ public JdbcType getElementJdbcType () {
195
+ return elementJdbcType ;
196
+ }
197
+
135
198
@ Override
136
199
public String toString () {
137
200
return ReactiveArrayJdbcType .class .getSimpleName () + "(" + getFriendlyName () + ")" ;
0 commit comments