当前位置: 首页 > 知识库问答 >
问题:

春数据卡桑德拉 1.3.2.版本是否支持 UDT 注释?

颜新
2023-03-14

Spring-data-Cassandra 1 . 3 . 2 . release是否支持@ UDT(http://docs . datas tax . com/en/developer/Java-driver/2.1/Java-driver/reference/mappingudts . html)?如果没有,我该如何添加解决方法

谢啦

共有2个答案

邓元白
2023-03-14

用户定义的数据类型现在由Spring数据卡桑德拉支持。最新版本1.5.0.RELEASE使用卡桑德拉数据斯塔克斯驱动程序3.1.3,因此它现在工作。请按照以下步骤使其正常工作

如何在Spring Data Cassandra中使用用户定义类型(UDT)功能:

>

  • 我们需要使用最新的Spring数据罐卡桑德拉(1.5.0.RELEASE)

    群组:' org.springframework.data ',名称:' spring-data-cassandra ',版本:' 1.5.0.RELEASE '

    确保它使用以下版本的jar:

    datastax . Cassandra . driver . version = 3 . 1 . 3 spring . data . Cassandra . version = 1 . 5 . 0 . release spring . data . commons . version = 1 . 13 . 0 . release spring . cql . version = 1 . 5 . 0 . release

    在卡桑德拉中创建用户定义类型:类型名称应与 POJO 类中定义的类型名称相同

    地址数据类型

    CREATE TYPE address_type ( 
        id text, 
        address_type text, 
        first_name text, 
        phone text 
    );
    

    创建柱族,其中一个柱为Cassandra中的UDT:

    员工表:

    创建表员工(employee_id uuid,employee_name文本,地址冻结,主键(employee_id,employee_name);

    在域类中,使用注释定义字段 -卡桑德拉类型,数据类型应为 UDT:

    @ Table(" Employee ")public class Employee {-othere fields-@ Cassandra type(type = DataType。Name.UDT,userTypeName = "address_type ")私人地址Address;}

    为用户定义类型创建域类:我们需要确保用户定义类型模式中的列名必须与域类中的字段名相同。

    @UserDefinedType(“address_type”) 公共类地址 { @CassandraType(类型 = 数据类型.名称.TEXT) 私有字符串 ID; @CassandraType(类型 = 数据类型.名称.TEXT) 私有字符串 address_type; }

    在Cassandra配置中,更改以下内容:

    @Bean公共 卡桑德拉映射上下文映射上下文() 抛出异常 { 基本卡桑德拉映射上下文 = 新基本卡桑德拉映射上下文 (); 映射Context.setUserTypeResolver(new SimpleUserTypeResolver(cluster().getObject(), cassandraKeyspace)); 返回 mappingContext; }

    用户定义的类型应该在所有地方都具有相同的名称。例如

    • @用户定义类型("address_type")
    • @CassandraType(type=DataType.Name.UDT, userTypeName="address_type")
    • 创建类型address_type

  • 胡俊美
    2023-03-14

    详情见此:https://jira.spring.io/browse/DATACASS-172

    我遇到了同样的问题,听起来好像没有(调试过程显示,Spring数据cassandra检查@Table,@Persistent或仅@PrimaryKeyClass注释,并在其他情况下引发异常

    但我找到了解决办法。我找到了一种方法,可以让我管理包含UDT和不包含它的实体。在我的应用程序中,我使用了spring cassandra data project和direct datastax核心驱动程序。不包含UDT对象的存储库使用spring cassanta数据方法,包含UDT的对象使用自定义存储库。自定义存储库使用datastax mapper,并且可以与UDT一起正常工作(它们位于单独的包中,请参见下面的注释,了解为什么需要它):

    package com.fyb.cassandra.custom.repositories.impl;
    
    import java.util.List;
    import java.util.UUID;
    
    import javax.annotation.PostConstruct;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.cassandra.config.CassandraSessionFactoryBean;
    
    import com.datastax.driver.core.ResultSet;
    import com.datastax.driver.mapping.Mapper;
    import com.datastax.driver.mapping.MappingManager;
    import com.datastax.driver.mapping.Result;
    import com.google.common.collect.Lists;
    import com.fyb.cassandra.custom.repositories.AccountDeviceRepository;
    import com.fyb.cassandra.dto.AccountDevice;
    
    public class AccountDeviceRepositoryImpl implements AccountDeviceRepository {
    
        @Autowired
        public CassandraSessionFactoryBean session;
    
        private Mapper<AccountDevice> mapper;
    
        @PostConstruct
        void initialize() {
            mapper = new MappingManager(session.getObject()).mapper(AccountDevice.class);
        }
    
        @Override
        public List<AccountDevice> findAll() {
            return fetchByQuery("SELECT * FROM account_devices");
        }
    
        @Override
        public void save(AccountDevice accountDevice) {
            mapper.save(accountDevice);
        }
    
        @Override
        public void deleteByCondithtml" target="_blank">ions(UUID accountId, UUID systemId, UUID deviceId) {
            final String query = "DELETE FROM account_devices where account_id =" + accountId + " AND system_id=" + systemId
                    + " AND device_id=" + deviceId;
            session.getObject().execute(query);
        }
    
        @Override
        public List<AccountDevice> findByAccountId(UUID accountId) {
            final String query = "SELECT * FROM account_devices where account_id=" + accountId;
            return fetchByQuery(query);
        }
    
        /*
         * Take any valid CQL query and try to map result set to the given list of appropriates <T> types.
         */
        private List<AccountDevice> fetchByQuery(String query) {
            ResultSet results = session.getObject().execute(query);
            Result<AccountDevice> accountsDevices = mapper.map(results);
            List<AccountDevice> result = Lists.newArrayList();
            for (AccountDevice accountsDevice : accountsDevices) {
                result.add(accountsDevice);
            }
            return result;
        }
    }
    

    负责管理不包含UDT对象的实体的与spring数据相关的repos如下所示:

    package com.fyb.cassandra.repositories;
    
    import org.springframework.data.cassandra.repository.CassandraRepository;
    
    import com.fyb.cassandra.dto.AccountUser;
    import org.springframework.data.cassandra.repository.Query;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    import java.util.UUID;
    
    @Repository
    public interface AccountUserRepository extends CassandraRepository<AccountUser> {
    
        @Query("SELECT * FROM account_users WHERE account_id=?0")
        List<AccountUser> findByAccountId(UUID accountId);
    }
    

    我已经测试了这个解决方案,它的作品100%。此外,我还附加了我的POJO对象:

    仅使用数据stax annatation的Pojo:

    package com.fyb.cassandra.dto;
    import java.util.List;
    import java.util.Map;
    import java.util.UUID;
    
    import com.datastax.driver.mapping.annotations.ClusteringColumn;
    import com.datastax.driver.mapping.annotations.Column;
    import com.datastax.driver.mapping.annotations.Frozen;
    import com.datastax.driver.mapping.annotations.FrozenValue;
    import com.datastax.driver.mapping.annotations.PartitionKey;
    import com.datastax.driver.mapping.annotations.Table;
    
    @Table(name = "account_systems")
    public class AccountSystem {
    
        @PartitionKey
        @Column(name = "account_id")
        private java.util.UUID accountId;
    
        @ClusteringColumn
        @Column(name = "system_id")
        private java.util.UUID systemId;
    
        @Frozen
        private Location location;
    
        @FrozenValue
        @Column(name = "user_token")
        private List<UserToken> userToken;
    
        @Column(name = "product_type_id")
        private int productTypeId;
    
        @Column(name = "serial_number")
        private String serialNumber;   
    }
    

    不使用UDT而只使用Spring数据卡桑德拉框架的Pojo:

    package com.fyb.cassandra.dto;
    
    import java.util.Date;
    import java.util.UUID;
    
    import org.springframework.cassandra.core.PrimaryKeyType;
    import org.springframework.data.cassandra.mapping.Column;
    import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
    import org.springframework.data.cassandra.mapping.Table;
    
    @Table(value = "accounts")
    public class Account {
    
        @PrimaryKeyColumn(name = "account_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
        private java.util.UUID accountId;
    
        @Column(value = "account_name")
        private String accountName;
    
        @Column(value = "currency")
        private String currency;    
    }
    

    请注意,下面的实体使用不同的注释:

    @PrimaryKeyColumn(name = "account_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)and @PartitionKey
    @ClusteringColumn and @PrimaryKeyColumn(name = "area_parent_id", ordinal = 2, type = PrimaryKeyType.CLUSTERED)
    

    乍一看,这很不舒服,但是它允许你处理包含和不包含UDT的对象。

    一个重要的注意事项。这两个repo(使用UDT且不应驻留在不同的包中)导致Spring config使用repo查找基本包:

    @Configuration
    @EnableCassandraRepositories(basePackages = {
            "com.fyb.cassandra.repositories" })
    public class CassandraConfig {
    ..........
    }
    
     类似资料:
    • 有人可以帮助我了解如何使用POJO类插入卡桑德拉UDT数据吗? 我创建了一个POJO类来映射Cassandra的表,并为Cassandra UDT创建了另一个类,但是当我插入映射Cassandra表的主POJO类时,它无法识别另一个POJO类(映射Cassandra的UDT)。我还在每个类和每个类对象上编写了注释。 这是我的一个POJO类:- 另一个POJO类:-

    • 我使用的是spring数据cassandra,需要使用jpa映射一个字段,在cassandra中,该字段的类型为

    • 我目前在cassandra中有一个名为macrecord的表,类似于以下内容: 在这种情况下,我想不出其他解决方案,只有在macadd值重复的情况下删除整行,然后插入具有更新时间戳的新行。 是否有更好的解决方案在macadd值重复时更新时间戳,或者在我的原始表中只有macadd是主键的范围内查询时间戳值的替代方法。

    • 我用Spring Data Cassandra 2.2.1开发了一个新的应用程序,想在Cassandra 2.1.9服务器上运行它(旧的,我知道)。但是我们得到了错误 Spring数据卡桑德拉手册声称Spring数据2.2.1至少需要卡桑德拉2.1,所以这应该有效,但它没有。我们包含的唯一特定于卡桑德拉的依赖项是 我怎样才能让这个工作?

    • 我对Cassandra相当陌生,在过去的一个月里读了很多书。 我正在研究一个小用例。 查询:基于在某个时间范围内播放的金额排名前 X 的玩家。 因此,在任何给定的时间范围内,我都希望汇总玩家的总游戏次数,并得出排名前X的玩家。 我遵循了创建UDF(使用C*-2.2.0版本)的方法,用于聚合AmountPlay by a Player。 下面是我为这个用例设计的时间序列数据模型。 请让我知道我的数据

    • 我正在尝试使用Cassandra 2.1升级到Spring Data Cassandra 1.5. x的Spring Boot 1.5,但出现启动错误: 未能实例化[org.springframework.data.cassandra.mapping.CassandraMappingContext]:工厂方法“cassandraMapping”引发异常;嵌套异常为java.lang.NoClass