[jOOQ/jOOQ#12208] Deeply nested MULTISET mappings with ad-hoc conversion doesn't work when using reflection
This commit is contained in:
parent
9c024ceae0
commit
cfbca6d72b
@ -223,5 +223,8 @@ public class Converters<T, U> extends AbstractConverter<T, U> {
|
||||
* {@link DataType#asConvertedDataTypeFrom(Function)} or
|
||||
* {@link DataType#asConvertedDataTypeTo(Function)}
|
||||
*/
|
||||
static final class UnknownType {}
|
||||
@Internal
|
||||
public static final class UnknownType {
|
||||
private UnknownType() {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,8 +332,9 @@ abstract class AbstractRecord extends AbstractStore implements Record {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> T get(Field<?> field, Class<? extends T> type) {
|
||||
return (T) converterOrFail(this, field.getType(), (Class) type).from(get(field));
|
||||
public final <U> U get(Field<?> field, Class<? extends U> type) {
|
||||
Object t = get(field);
|
||||
return (U) converterOrFail(this, t, (Class) field.getType(), type).from(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -347,8 +348,9 @@ abstract class AbstractRecord extends AbstractStore implements Record {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> T get(int index, Class<? extends T> type) {
|
||||
return (T) converterOrFail(this, field(safeIndex(index)).getType(), (Class) type).from(get(index));
|
||||
public final <U> U get(int index, Class<? extends U> type) {
|
||||
Object t = get(index);
|
||||
return (U) converterOrFail(this, t, (Class) field(safeIndex(index)).getType(), type).from(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -394,7 +394,7 @@ public class DefaultRecordMapper<R extends Record, E> implements RecordMapper<R,
|
||||
}
|
||||
|
||||
// [#10071] Single-field Record1 types can be mapped if there is a ConverterProvider allowing for this mapping
|
||||
if ((debugVTFL = fields.length == 1) && (debugVTCP = Tools.converter(configuration, fields[0].getType(), type) != null)) {
|
||||
if ((debugVTFL = fields.length == 1) && (debugVTCP = Tools.converter(configuration, instance, (Class) fields[0].getType(), type) != null)) {
|
||||
delegate = new ValueTypeMapper();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ final class FieldsImpl<R extends Record> extends AbstractQueryPart implements Re
|
||||
|
||||
@Override
|
||||
public final <U> RecordMapper<R, U> mapper(int fieldIndex, Configuration configuration, Class<? extends U> type) {
|
||||
return mapper(fieldIndex, converterOrFail(configuration, fields[safeIndex(fieldIndex)].getType(), type));
|
||||
return mapper(fieldIndex, converterOrFail(configuration, null, fields[safeIndex(fieldIndex)].getType(), type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,7 +121,7 @@ final class FieldsImpl<R extends Record> extends AbstractQueryPart implements Re
|
||||
|
||||
@Override
|
||||
public final <U> RecordMapper<R, U> mapper(String fieldName, Configuration configuration, Class<? extends U> type) {
|
||||
return mapper(fieldName, converterOrFail(configuration, field(indexOrFail(this, fieldName)).getType(), type));
|
||||
return mapper(fieldName, converterOrFail(configuration, null, field(indexOrFail(this, fieldName)).getType(), type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -141,7 +141,7 @@ final class FieldsImpl<R extends Record> extends AbstractQueryPart implements Re
|
||||
|
||||
@Override
|
||||
public final <U> RecordMapper<R, U> mapper(Name fieldName, Configuration configuration, Class<? extends U> type) {
|
||||
return mapper(fieldName, converterOrFail(configuration, field(indexOrFail(this, fieldName)).getType(), type));
|
||||
return mapper(fieldName, converterOrFail(configuration, null, field(indexOrFail(this, fieldName)).getType(), type));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -163,7 +163,7 @@ final class FieldsImpl<R extends Record> extends AbstractQueryPart implements Re
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public final <U> RecordMapper<R, U> mapper(Field<?> field, Configuration configuration, Class<? extends U> type) {
|
||||
return mapper(field, (Converter) converterOrFail(configuration, field.getType(), type));
|
||||
return mapper(field, (Converter) converterOrFail(configuration, null, field.getType(), type));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@ -247,6 +247,7 @@ import org.jooq.Configuration;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ConverterProvider;
|
||||
import org.jooq.Converters;
|
||||
import org.jooq.Cursor;
|
||||
import org.jooq.DMLQuery;
|
||||
import org.jooq.DSLContext;
|
||||
@ -1253,11 +1254,18 @@ final class Tools {
|
||||
* Get a converter from a {@link ConverterProvider} or <code>null</code> if
|
||||
* no converter could be provided.
|
||||
*/
|
||||
static final <T, U> Converter<T, U> converter(Configuration configuration, Class<T> tType, Class<U> uType) {
|
||||
static final <T, U> Converter<T, U> converter(Configuration configuration, T instance, Class<T> tType, Class<U> uType) {
|
||||
Converter<T, U> result = configuration(configuration).converterProvider().provide(tType, uType);
|
||||
|
||||
if (result == null)
|
||||
result = CTX.configuration().converterProvider().provide(tType, uType);
|
||||
|
||||
// [#11823] [#12208] The new ad-hoc conversion API tries to avoid the Class<U> literal
|
||||
// meaning there are perfectly reasonable API usages when using MULTISET
|
||||
// where we can't decide on a converter prior to having an actual result
|
||||
// type - so, let's try again if we have the result value.
|
||||
if (result == null && tType == Converters.UnknownType.class)
|
||||
result = converter(configuration, instance, (Class<T>) (instance == null ? Object.class : instance.getClass()), uType);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1266,8 +1274,8 @@ final class Tools {
|
||||
* Get a converter from a {@link ConverterProvider} or <code>null</code> if
|
||||
* no converter could be provided.
|
||||
*/
|
||||
static final <T, U> Converter<T, U> converterOrFail(Configuration configuration, Class<T> tType, Class<U> uType) {
|
||||
Converter<T, U> result = converter(configuration, tType, uType);
|
||||
static final <T, U> Converter<T, U> converterOrFail(Configuration configuration, T instance, Class<T> tType, Class<U> uType) {
|
||||
Converter<T, U> result = converter(configuration, instance, tType, uType);
|
||||
|
||||
if (result == null)
|
||||
throw new DataTypeException("No Converter found for types " + tType.getName() + " and " + uType.getName());
|
||||
@ -1278,8 +1286,8 @@ final class Tools {
|
||||
/**
|
||||
* Get a converter from a {@link ConverterProvider}.
|
||||
*/
|
||||
static final <T, U> Converter<T, U> converterOrFail(Attachable attachable, Class<T> tType, Class<U> uType) {
|
||||
return converterOrFail(configuration(attachable), tType, uType);
|
||||
static final <T, U> Converter<T, U> converterOrFail(Attachable attachable, T instance, Class<T> tType, Class<U> uType) {
|
||||
return converterOrFail(configuration(attachable), instance, tType, uType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user