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

Spring项目Cassandra UDT写入报错:Cannot resolve UserDefinedType for [device_list]

问题:Spring项目操作Cassandra写入含UDT的表失败,报错Cannot resolve UserDefinedType for [device_list]

在Spring项目中向包含UDT的Cassandra表写入数据时失败,报错信息为Cannot resolve UserDefinedType for [device_list]。

项目依赖

//cassandra
implementation 'org.springframework.data:spring-data-cassandra:3.1.2'
implementation 'io.projectreactor:reactor-core'
implementation 'com.datastax.cassandra:cassandra-driver-core:3.10.2'
implementation 'com.datastax.oss:java-driver-mapper-runtime:4.13.0'
implementation 'com.datastax.oss:java-driver-core:4.13.0'
implementation 'com.datastax.cassandra:cassandra-driver-mapping:3.6.0'

Java版本

java --version
openjdk 11.0.18 2023-01-17 LTS
OpenJDK Runtime Environment Corretto-11.0.18.10.1 (build 11.0.18+10-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.18.10.1 (build 11.0.18+10-LTS, mixed mode)

实体类代码

import com.datastax.driver.core.DataType;
import com.xxx.pai.gm.ws.core.model.Widgets;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.cassandra.core.cql.Ordering;
import org.springframework.data.cassandra.core.cql.PrimaryKeyType;
import org.springframework.data.cassandra.core.mapping.CassandraType;
import org.springframework.data.cassandra.core.mapping.Column;
import org.springframework.data.cassandra.core.mapping.Frozen;
import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn;
import org.springframework.data.cassandra.core.mapping.Table;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("shortcut_widgets")
public class ShortcutWidgetEntity {
    @PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED, ordering = Ordering.ASCENDING)
    @Column("customerId")
    private String customerId;

    @Frozen
    @Column("device_list")
    @CassandraType(type = CassandraType.Name.LIST, userTypeName = "device_list", typeArguments = CassandraType.Name.UDT)
    List<Devices> deviceList;
}

UDT类代码

import com.datastax.driver.mapping.annotations.Field;
import com.datastax.driver.mapping.annotations.UDT;
import com.xxx.pai.gm.ws.core.controller.request.ShortcutWidgets;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.cassandra.core.mapping.UserDefinedType;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@UserDefinedType("device_list")
public class Devices {
    private Long bannerId;
    private String uniqueId;
    private String type;
    private String imageUrl;
    private String darkImageUrl;
    private String url;
    private String title;
    private Integer metaDataSourceId;
}

Cassandra表结构

create TYPE device_list( bannerId bigint, uniqueId text, type text, 
        imageUrl text, darkImageUrl text, url text, title text, 
        metaDataSourceId int );

CREATE TABLE shortcut_widgets (
    customerId text PRIMARY KEY,
    device_list frozen<list<device_list>>
);

Repository代码

@Repository
public class ShortcutWidgetsRepository {
    private static final String KEYSPACE_NAME = "shortcuts";
    private final MeterRegistry meterRegistry;
    private final ReactiveCassandraTemplate template; 

    public ShortcutWidgetsRepository(
    @Qualifier("cassandraTemplate1") ReactiveCassandraTemplate template,
    MeterRegistry meterRegistry) {
        this.template = template;
        this.meterRegistry = meterRegistry;
    }

    public Mono<ShortcutWidgetEntity> saveWidget(ShortcutWidgetEntity shortcutWidgetEntity) {
        return template.insert(shortcutWidgetEntity);
    }
}

已尝试操作

  • 调整依赖版本,但因依赖冲突无法注入Session Bean,问题未解决
  • 参考相关博客内容,未找到有效解决方案

解决方案

1. 统一Cassandra驱动版本,消除依赖冲突

当前依赖混合了DataStax驱动3.x和4.x版本,这是核心问题。Spring Data Cassandra 3.1.2对应DataStax OSS驱动4.x系列,需移除所有3.x版本驱动依赖:

修改后的依赖:

//cassandra
implementation 'org.springframework.data:spring-data-cassandra:3.1.2'
implementation 'io.projectreactor:reactor-core'
// 仅保留4.x版本驱动
implementation 'com.datastax.oss:java-driver-core:4.13.0'
implementation 'com.datastax.oss:java-driver-mapper-runtime:4.13.0'

2. 修正UDT类注解

移除DataStax 3.x的@UDT/@Field注解,使用Spring Data Cassandra的@UserDefinedType并指定对应keyspace:

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.cassandra.core.mapping.UserDefinedType;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
// 指定UDT所属的keyspace,需与创建UDT的keyspace一致
@UserDefinedType(value = "device_list", keyspace = "shortcuts")
public class Devices {
    private Long bannerId;
    private String uniqueId;
    private String type;
    private String imageUrl;
    private String darkImageUrl;
    private String url;
    private String title;
    private Integer metaDataSourceId;
}

3. 修正实体类中UDT集合的注解

调整@CassandraType参数配置,确保类型映射正确:

@Frozen
@Column("device_list")
// 对于UDT集合,typeArguments指定UDT类型,userTypeName指定Cassandra中的UDT名称
@CassandraType(type = CassandraType.Name.LIST, typeArguments = CassandraType.Name.UDT, userTypeName = "device_list")
List<Devices> deviceList;

4. 确保Spring扫描到UDT类

在Cassandra配置类中指定UDT所在包路径,让Spring能识别并注册UDT类型:

import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.EnableReactiveCassandraRepositories;
import org.springframework.data.cassandra.repository.config.CassandraMappingContextConfiguration;

@Configuration
@EnableReactiveCassandraRepositories(basePackages = "com.xxx.pai.gm.ws.repository")
// 指定UDT类所在包
@CassandraMappingContextConfiguration(basePackages = "com.xxx.pai.gm.ws.model.udt")
public class CassandraConfig {
    // 可添加Cassandra连接配置,如SessionFactory等
}

5. 验证Cassandra中UDT的存在

执行以下CQL确认shortcuts keyspace下存在device_list类型:

USE shortcuts;
DESCRIBE TYPE device_list;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:25:55