如何修复使用 Hibernate Search DSL 时 Koltin 中的泛型错误

问题描述 投票:0回答:1

以下java代码在java中运行良好:

import org.hibernate.search.engine.search.predicate.dsl.MatchPredicateOptionsStep
import org.hibernate.search.engine.search.predicate.dsl.SearchPredicateFactory
import org.hibernate.search.engine.search.query.SearchResult
import org.hibernate.search.mapper.orm.Search
import org.springframework.data.domain.Pageable
// ...... omit

    SearchSession searchSession = Search.session(entityManager);
    SearchResult<MediaAsset> hits = searchSession.search(MediaAsset.class)
            .where(f -> f.match().field("tag").matching(tagName))
            .fetch(offset, pageable.getPageSize());

但是,如果我将其转换为 kotlin,它无法解析泛型。

// below SearchResult can only resolve to 'out Any' not MediaAsset class
val hits: SearchResult<out Any> = searchSession.search(MediaAsset::class.java)
            .where { f: SearchPredicateFactory -> f.match().field("tag").matching(tagName) }
            .fetch(offset, pageable.pageSize)

IntelliJ Java 到 Kotlin 自动转换也给出了这个结果。如何修复泛型?

java kotlin generics hibernate-search
1个回答
0
投票

对此持保留态度,因为我根本不使用 Kotlin,但据我所知,Kotlin 无法解析

select
返回类型的第一个泛型参数,因此您的解决方法是投射
select
的结果:

val hits: SearchResult<MediaAsset> = (searchSession.search(MediaAsset::class.java)
                as SearchQuerySelectStep<out SearchQueryOptionsStep<*, MyKotlinEntity, *, *, *>, MyKotlinEntity, *, *, *, *>)
            .where { f: SearchPredicateFactory -> f.match().field("tag").matching(tagName) }
            .fetch(offset, pageable.pageSize)

是的,它很丑陋,但它是针对 Kotlin 处理 Java 接口泛型的限制的一种解决方法 ́\_(ツ)_/̊ 。有趣的是,Kotlin 在其他领域的泛型方面可以说要好得多……

其他人也曾受过此打击,例如here(法语)的人们简短地提到了这一点,但我认为他们没有提供解决方案。

如果您有建议让 DSL 更好地与 Kotlin 配合使用,同时又不破坏 Java 的向后兼容性,我很高兴听到它们。例如。也许 Kotlin 支持某种扩展方法,可以覆盖 Java 定义并允许我们让 Kotlin 编译器的行为与 Java 类似?我真的不知道...

编辑:FWIW我创建了https://hibernate.atlassian.net/browse/HSEARCH-5003,但到目前为止我不知道如何改进,所以......欢迎提出想法:)

© www.soinside.com 2019 - 2024. All rights reserved.