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

Spring Data Cassandra无法直接通过复合主键查询数据问题

解决Spring Data Cassandra复合主键查询的QueryCreationException问题

嘿,我太懂这个坑了!你遇到的这个QueryCreationException核心原因就是Spring Data Cassandra不允许直接把整个复合主键类作为查询参数,必须明确引用主键类里的具体属性才行——异常提示里已经把原因说得明明白白:Cannot use composite primary key directly. Reference a property of the composite primary key。

给你两种靠谱的解决方案,结合你的代码场景来调整:

方案1:使用Spring Data命名查询规则(推荐)

首先确认你的复合主键类(带@PrimaryKeyClass注解的Key类)的结构,比如假设它是这样的:

@PrimaryKeyClass
public class Key implements Serializable {
    @PrimaryKeyColumn(name = "service_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
    private String serviceId;

    @PrimaryKeyColumn(name = "version", ordinal = 1, type = PrimaryKeyType.CLUSTERED)
    private Integer version;

    // 记得实现构造器、getter、setter,以及正确重写equals()和hashCode()方法
}

然后修改你的ServiceRepository接口,把原有的findByKey(Key key)方法,改成引用主键类里的具体属性:

public interface ServiceRepository extends CassandraRepository<ServiceEntity, Key> {
    // 按完整复合主键查询(等价于传整个Key对象的效果)
    List<ServiceEntity> findByKeyServiceIdAndKeyVersion(String serviceId, Integer version);

    // 如果只需要按分区键查询(比如查询某个serviceId下的所有版本数据)
    List<ServiceEntity> findByKeyServiceId(String serviceId);
}

这里的命名规则是:用实体类中复合主键字段的名称(比如key)作为前缀,后面跟上主键类里的属性名,多个属性用And连接,Spring Data会自动解析成对应的CQL查询。

方案2:用@Query注解自定义查询(保留原方法签名)

如果你想保留findByKey(Key key)这个方法签名,不想拆分参数,可以用@Query注解直接写CQL语句:

public interface ServiceRepository extends CassandraRepository<ServiceEntity, Key> {
    @Query("SELECT * FROM service WHERE service_id = ?0.serviceId AND version = ?0.version")
    List<ServiceEntity> findByKey(Key key);
}

这里的?0代表方法的第一个参数(也就是你的Key对象),直接引用它的属性serviceId和version即可,Cassandra会正确解析这个参数。

额外注意点

  • 复合主键类必须实现Serializable接口,并且正确重写equals()和hashCode()方法,这是Spring Data Cassandra对主键类的强制要求。
  • 命名查询的属性名要和实体类、主键类的getter方法对应,避免因名称不匹配导致解析失败。

内容的提问来源于stack exchange,提问作者Gekster

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:26:41