使用Hibernate Search DSL时如何修复Kotlin泛型错误
Hibernate Search Kotlin泛型解析问题修复
问题场景
Java版本的Hibernate Search查询代码可正常解析泛型SearchResult<MediaAsset>:
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; // ...... 省略其他代码 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后,编译器无法正确推断泛型,SearchResult只能解析为SearchResult<out Any>:
// 此处SearchResult只能解析为'out Any',而非MediaAsset类型 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自动转换也会出现该问题。
修复方案
显式指定泛型参数:在
search方法调用时明确声明泛型类型,强制编译器锁定目标实体类型:val hits: SearchResult<MediaAsset> = searchSession.search<MediaAsset>(MediaAsset::class.java) .where { f -> f.match().field("tag").matching(tagName) } .fetch(offset, pageable.pageSize)简化lambda参数声明:移除lambda中
SearchPredicateFactory的显式类型标注,让编译器通过上下文自动关联泛型:val hits = searchSession.search(MediaAsset::class.java) .where { it.match().field("tag").matching(tagName) } .fetch(offset, pageable.pageSize) // 此时hits会被正确推断为SearchResult<MediaAsset>分步调用指定中间类型:若前两种方法不生效,可拆分查询构建步骤,为中间的查询构建器指定泛型:
val searchQueryBuilder = searchSession.search<MediaAsset>(MediaAsset::class.java) .where { f -> f.match().field("tag").matching(tagName) } val hits: SearchResult<MediaAsset> = searchQueryBuilder.fetch(offset, pageable.pageSize)
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

