I have a postgres database with some columns that are of type varchar[]
. jOOQ and pgjdbc-ng aren't playing along nicely; jOOQ's DefaultBindContext has something along the lines of:
protected final BindContext bindValue0(Object value, Field<?> field) throws SQLException {
SQLDialect dialect = configuration.dialect();
// [#650] [#3108] Use the Field's Converter before actually binding any value
Converter<?, ?> converter = field.getConverter();
Class<?> type = converter.fromType();
value = ((Converter) converter).to(value);
//...
else if (type.isArray()) {
switch (dialect) {
case POSTGRES: {
stmt.setString(nextIndex(), toPGArrayString((Object[]) value));
break;
}
Which sets the statement variable to "{\"value1\", \"value2\", \"etc\"}"
, which is how you'd specify an array in a query. Later on, pgjdbc-ng has:
public static Object coerceToArray(Format format, Object val, Type type, Class<?> targetType, Map<String, Class<?>> typeMap, PGConnectionImpl connection) throws SQLException {
if (val == null) {
return null;
}
else if (val instanceof PGArray) {
return coerceToArray(format, ((PGArray) val).getValue(), type, targetType, typeMap, connection);
}
else if (val.getClass().isArray()) {
return coerceToArray(format, val, 0, Array.getLength(val), type, targetType, typeMap, connection);
}
throw createCoercionException(val.getClass(), targetType);
}
Which expects that the value on the statement will be of either type PGArray or an actual array; it fails to coerce the String representation of an array into a String representation of an array. :(
I am trying to write a jOOQ Converter that will convert between String[]
and PGArray
; ideally, this would mean that jOOQ's DefaultBindContext would leave the converted value well enough alone, and then pgjdbc-ng would be able to handle it correctly.
However, I have been unable to write a jOOQ schema configuration that allows me to do this. I've tried variations on:
<customType>
<customType>
<name>StringArray</name>
<type>java.lang.String[]</type>
<converter>my.package.PGStringArrayConverter</converter>
</customType>
</customTypes>
<forcedTypes>
<forcedType>
<name>StringArray</name>
<types>varchar\[\]</types>
</forcedType>
</forcedTypes>
Without having any luck; the generated table objects refer to a String[][]
, and varchar[]
doesn't match on anything. Even if I break it down, so that the forcedType matches on any type but with an <expression>
that only matches my column, and the Converter's type is java.lang.String
, I end up with the java compiler complaining about being unable to cast Object[] to String[].
Is there any light at the end of this tunnel, or should I start looking to migrate my database?