无法使用 UDT 写入表,出现“无法解析 [设备] 的 UserDefinedType”

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

这些是我在 spring 项目中安装的依赖项

//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 --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;
}

我无法将数据写入表和UDT,如下:

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
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);
    }
}

我面临的错误是

"Cannot resolve UserDefinedType for \[device_list\]"

我尝试过更改依赖项的版本,尝试遵循此博客https://www.linkedin.com/pulse/guide-cassandra-object-mapper-spring-nikunj-pandya/,但是使用注入会话bean时出现问题我现在拥有的依赖关系。谁能帮我,如何解决这个错误?

java cassandra datastax-java-driver user-defined-types spring-data-cassandra
1个回答
0
投票

我注意到您正在使用 Spring Data Cassandra v3.1.2:

implementation 'org.springframework.data:spring-data-cassandra:3.1.2'

您需要检查代码中的依赖项,因为根据 官方 Spring Data 参考文档Maven 编译依赖项

spring-data-cassandra
v3.1.2 需要 Cassandra Java 驱动程序 4.0 或更高版本。

此外,您的 UDT 类已经使用了

@UserDefinedType
注释:

@UserDefinedType("device_list")
public class Devices {
    ...
}

所以你不应该在实体类中使用

@CassandraType
注释:

public class ShortcutWidgetEntity {
    ...

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

就其价值而言,Aaron Ploetz 在 GitHub 上有一个电子商务应用程序的工作示例,并具有完整的源代码。在其中您将看到他如何实现 UDT 的映射器。

话虽如此,我强烈建议仅将 UDT 作为最后的手段。只要有可能,您就应该使用本机 CQL 类型并在常规列/行中对数据进行建模。除非您有使用 UDT 的非常具体的需求,否则我建议您使用以下内容对数据进行建模:

CREATE TABLE widgets_by_customer_id (
    customer_id text,
    device_id text,
    ...
    PRIMARY KEY(customer_id, device_id)
)

使用此架构,每个客户将拥有一行或多行设备。这意味着 (1) 您可以分页浏览所有设备,(2) 您可以检索单个设备,而无需检索整个

list
集合,(3) 更新架构(添加/删除)要容易得多列)在未来。干杯!

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