Jdbi: При использовании лямбда: «Здесь необходимо использовать конкретно типизированный RowMapper»

Созданный на 9 апр. 2018  ·  3Комментарии  ·  Источник: jdbi/jdbi

Прежде всего: спасибо за эту потрясающую библиотеку! Мы медленно переходим с Hibernate на jdbi и пока очень им довольны;)

Предположим, у меня есть следующий код:

getHandle().createQuery("SELECT ...")
    .bind("id", id)
    .registerRowMapper((RowMapper<CatalogueJdbi>) (rs, ctx) -> {
        final CatalogueJdbi catalogue = FieldMapper.of(CatalogueJdbi.class, "c").map(rs, ctx);
        if (rs.getObject("mid") != null) {
            catalogue.setImage(FieldMapper.of(MediaFileJdbi.class, "m").map(rs, ctx));
        }

        return catalogue;
    })
    .mapTo(CatalogueJdbi.class)
    .collect(Collectors.toSet());

При регистрации RowMapper, как показано, я получаю

java.lang.UnsupportedOperationException: Must use a concretely typed RowMapper here
    at org.jdbi.v3.core.mapper.InferredRowMapperFactory.lambda$new$0(InferredRowMapperFactory.java:38)
    at java.base/java.util.Optional.orElseThrow(Optional.java:385)
    at org.jdbi.v3.core.mapper.InferredRowMapperFactory.<init>(InferredRowMapperFactory.java:38)
    at org.jdbi.v3.core.mapper.RowMappers.register(RowMappers.java:63)
    at org.jdbi.v3.core.config.Configurable.lambda$registerRowMapper$16(Configurable.java:248)
    at org.jdbi.v3.core.config.Configurable.configure(Configurable.java:74)
    at org.jdbi.v3.core.config.Configurable.registerRowMapper(Configurable.java:248)
    at ...

но при использовании

.registerRowMapper(new RowMapper<CatalogueJdbi>() {
                    <strong i="13">@Override</strong>
                    public CatalogueJdbi map(final ResultSet rs, final StatementContext ctx) throws SQLException {
                        final CatalogueJdbi catalogue = FieldMapper.of(CatalogueJdbi.class, "c").map(rs, ctx);
                        if (rs.getObject("mid") != null) {
                            catalogue.setImage(FieldMapper.of(MediaFileJdbi.class, "m").map(rs, ctx));
                        }

                        return catalogue;
                    }
                })

вместо этого все работает нормально.

Я думал, лямбды - это всего лишь синтаксический сахар, и компилятор все равно расширит код?

question

Самый полезный комментарий

Из-за общего стирания параметр <CatalogueJdbi> теряется во время выполнения, поэтому Jdbi не знает, какой тип соответствует этому сопоставителю.

Вы можете использовать альтернативный метод, в котором вы передаете тип как отдельный параметр:

.registerRowMapper(CatalogueJdbi.class, (rs, ctx) -> { ... })

Следует отметить одно: регистрация преобразователя строк с последующим вызовом mapTo(type) - это напрасная трата усилий, если этот преобразователь больше нигде не используется. Вы можете просто вызвать метод map(RowMapper<T>) и передать ему лямбду:

.map((rs, ctx) -> { ... })

Все 3 Комментарий

Из-за общего стирания параметр <CatalogueJdbi> теряется во время выполнения, поэтому Jdbi не знает, какой тип соответствует этому сопоставителю.

Вы можете использовать альтернативный метод, в котором вы передаете тип как отдельный параметр:

.registerRowMapper(CatalogueJdbi.class, (rs, ctx) -> { ... })

Следует отметить одно: регистрация преобразователя строк с последующим вызовом mapTo(type) - это напрасная трата усилий, если этот преобразователь больше нигде не используется. Вы можете просто вызвать метод map(RowMapper<T>) и передать ему лямбду:

.map((rs, ctx) -> { ... })

Я знал, что делаю что-то не так :) Большое спасибо!

Как продолжение: когда вы создаете анонимный внутренний класс, вы создаете конкретно типизированный картограф.

Под конкретно типизированным мы подразумеваем то, что Jdbi может получить класс сопоставителя и рефлексивно обнаружить общий параметр T для RowMapper<T> . Делаете ли вы это через полноценный класс, например class FooMapper implements RowMapper<Foo> { ... } или через анонимный внутренний класс, например, new RowMapper<Foo>() { ... } , для Jdbi это выглядит одинаково.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги