You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Spring Boot(Kotlin+Redis OM Spring)中使用投影查询Redis JSON指定字段返回null的问题排查

在Spring Boot(Kotlin+Redis OM Spring)中使用投影查询Redis JSON指定字段返回null的问题排查

我帮你捋捋这个问题哈,你现在遇到的情况是Redis CLI里明明能查到正确的number和location数据,但Spring这边用投影接口返回的全是null,这其实是Redis OM Spring结合Kotlin使用投影时的一个常见小问题,咱们一步步来解决:

1. 先搞懂问题出在哪

你在Redis CLI里看到的查询结果是完全正常的,说明Redis那边的FT.SEARCH命令执行没问题,问题出在Spring端把Redis返回的结果映射到Stat接口实例的过程中,主要有两个核心原因:

  • Kotlin接口投影默认生成的代理类,没法正确触发Redis OM Spring对Point这类Geo复杂类型的反序列化逻辑;
  • Redis OM Spring在Kotlin下对接口属性的访问器(也就是Getter方法)的识别逻辑和Java略有差异,导致没法把Redis返回的字段值正确绑定到接口属性上。

2. 最靠谱的解决方案:用数据类代替接口做投影

Spring Data的DTO投影(也就是用数据类做投影)会通过构造函数直接绑定字段值,比接口投影更稳定,尤其是处理Point这种复杂类型的时候,咱们这么改:

第一步:把投影接口改成Kotlin数据类

import org.springframework.data.geo.Point

// 用数据类替代原来的Stat接口
data class Stat(
    val number: String,
    val location: Point
)

第二步:修改Repository的返回类型

interface MarkerRepo : RedisDocumentRepository<RedisMarker, String> {
    // 返回List<Stat>,对应新的投影数据类
    fun findByNumber(number: String): List<Stat>
}

改完之后,Redis OM Spring就能正确把Redis返回的number字符串和location坐标字符串,反序列化成Stat数据类的实例,不会再返回null列表啦。

3. 要是坚持用接口投影,试试这个调整

如果你一定要用接口作为投影,可以给接口的属性加上@JsonProperty注解,明确指定和Redis返回字段的映射关系,帮Spring正确识别字段:

import com.fasterxml.jackson.annotation.JsonProperty
import org.springframework.data.geo.Point

interface Stat {
    @JsonProperty("number")
    val number: String

    @JsonProperty("location")
    val location: Point
}

不过这个方案的稳定性不如数据类投影,因为Kotlin接口生成的代理类逻辑和Java有细微差异,复杂类型的反序列化还是可能出问题,所以更推荐用数据类的方案。

4. 最后再提两个注意点

  • 确保你的Redis OM Spring是最新稳定版本,旧版本可能存在Kotlin投影的兼容性bug;
  • 检查Point类型的导入:必须是org.springframework.data.geo.Point,这是Redis OM Spring默认支持的Geo类型,别用自定义的Point类,不然反序列化肯定失败。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 09:19:31