JOOQ - встроенный конвертер не применяется - PullRequest
3 голосов
/ 13 июля 2020

В моем build.gradle я использую конвертер в моем forcedTypes. Это отлично работает там, где мне это нужно.

forcedType {
    userType = 'java.util.List<stormsensor.thor.dto.telemetry.FlowEventType>'
    converter = 'stormsensor.thor.config.jooq.StringToFlowEventTypeListConverter'
    includeExpression = '.*\\.FLOW_EVENTS'
    includeTypes = '.*'
}

Однако я пытаюсь преобразовать строку, разделенную запятыми, в список перечислений для конкретного случая использования:

DataType<List<FlowEventType>> LIST_TYPE = SQLDataType.VARCHAR.asConvertedDataType(new StringToFlowEventTypeListConverter());

ctx.select(
  groupConcatDistinct(NOTIFICATION_RULE.FLOW_EVENT_TYPE).as(field(name("notifications"), LIST_TYPE))
)
.from(NOTIFICATION_RULE)
.groupBy(MONITORING_POINT_ID)
.fetchInto(BatchNotificationRuleModel.class);

Это вызывает исключение

org.jooq.exception.MappingException: An error ocurred when mapping record to class stormsensor.thor.dto.notification.batch.BatchNotificationRuleModel
    at org.jooq.impl.DefaultRecordMapper$MutablePOJOMapper.map(DefaultRecordMapper.java:802)
    at org.jooq.impl.DefaultRecordMapper.map(DefaultRecordMapper.java:500)
    at org.jooq.impl.ResultImpl.into(ResultImpl.java:1284)
    at org.jooq.impl.AbstractResultQuery.fetchInto(AbstractResultQuery.java:1550)
    at org.jooq.impl.SelectImpl.fetchInto(SelectImpl.java:3746)
    at stormsensor.thor.repository.notification.BatchNotificationRuleRepositoryJdbcImpl.save(BatchNotificationRuleRepositoryJdbcImpl.java:98)
Caused by: org.jooq.exception.DataTypeException: Cannot convert from CRITICAL_DEPTH,NON_TIDAL_CSO (class java.lang.String) to interface java.util.List
    at org.jooq.tools.Convert$ConvertAll.fail(Convert.java:1194)
    at org.jooq.tools.Convert$ConvertAll.from(Convert.java:1083)
    at org.jooq.tools.Convert.convert0(Convert.java:324)
    at org.jooq.tools.Convert.convert(Convert.java:316)
    at org.jooq.tools.Convert.convert(Convert.java:387)
    at org.jooq.impl.AbstractRecord.get(AbstractRecord.java:275)
    at org.jooq.impl.DefaultRecordMapper$MutablePOJOMapper.map(DefaultRecordMapper.java:830)
    at org.jooq.impl.DefaultRecordMapper$MutablePOJOMapper.map(DefaultRecordMapper.java:762)
    ... 72 more

Это модель, в которую я загружаю:

@Data
@NoArgsConstructor
public class BatchNotificationRuleModel implements Serializable {
    private static final long serialVersionUID = 1L;

    private List<FlowEventType> notifications;
    private List<MessageProtocolType> protocols;
}

Я что-то упускаю?

ОБНОВЛЕНИЕ:

Я могу для встроенного преобразования с использованием

//...
.groupBy(MONITORING_POINT_ID)
.fetchStream().map(e -> {
    Converter<String, List<FlowEventType>> converter = new StringToFlowEventTypeListConverter();
    List<FlowEventType> notifications = e.get(field(name("notifications"), String.class), converter);
    return BatchNotificationRuleModel.builder().notifications(notifications).build();
}).collect(toList());

В чем разница между исходным преобразователем, который я применяю, и преобразованием карты на позднем этапе?

1 Ответ

1 голос
/ 14 июля 2020

Хотя кажется разумным ожидать, что Field.as(Field) будет использовать имя поля аргумента и тип для приведения типа, это не так. Согласно Javado c:

Создайте псевдоним для этого поля на основе имени другого поля.

Чтобы привести ваше выражение к желаемому типу данных, вы должны сделать это вручную:

groupConcatDistinct(NOTIFICATION_RULE.FLOW_EVENT_TYPE)
  .coerce(LIST_TYPE)
  .as("notifications")

См. Field.coerce(DataType)

...