首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring-data-Cassandra 1.3.2. support支持UDT注释吗?

Spring-data-Cassandra 1.3.2. support支持UDT注释吗?
EN

Stack Overflow用户
提问于 2016-01-12 21:06:08
回答 2查看 1.9K关注 0票数 1

@UDT (http://docs.datastax.com/en/developer/java-driver/2.1/java-driver/reference/mappingUdts.html)是否由Spring支持-Cassandra1.3.2.RELEASE?如果没有,我如何为这个添加解决方法?

谢谢

EN

回答 2

Stack Overflow用户

发布于 2016-02-26 08:51:20

请参阅这里的详细信息:https://jira.spring.io/browse/DATACASS-172

我也面临着同样的问题,听起来似乎并非如此(调试过程显示,spring data cassandra只检查@Table、@Persistent或@PrimaryKeyClass注解,并在其他情况下引发异常)。

调用init方法失败;嵌套异常是org.springframework.data.cassandra.mapping.VerifierMappingExceptions:卡桑德拉实体必须具有@Table、@Persistent或@PrimaryKeyClass注释

但我找到了解决办法。在我的应用程序中,我使用spring数据项目和使用直接datastax核心驱动程序。不包含带有UDT的对象的存储库使用spring数据方法,而包含UDT的对象使用自定义存储库。自定义存储库使用datastax,并正确地使用UDT (它们位于单独的包中,请参见下面说明为什么需要UDT):

代码语言:javascript
复制
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 deleteByConditions(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看起来如下所示:

代码语言:javascript
复制
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对象:

Pojo,它只使用data年期:

代码语言:javascript
复制
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;   
}

Pojo不使用UDT,只使用spring data cassandra框架:

代码语言:javascript
复制
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;    
}

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

代码语言:javascript
复制
@PrimaryKeyColumn(name = "account_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED)and @PartitionKey
@ClusteringColumn and @PrimaryKeyColumn(name = "area_parent_id", ordinal = 2, type = PrimaryKeyType.CLUSTERED)

乍一看-这是不舒服的,但它允许你工作的对象,包括UDT和不。

一个重要的音符。两个repos(使用UDT而不应该驻留在不同的包中)导致Spring配置查找带有repos的基本包:

代码语言:javascript
复制
@Configuration
@EnableCassandraRepositories(basePackages = {
        "com.fyb.cassandra.repositories" })
public class CassandraConfig {
..........
}
票数 3
EN

Stack Overflow用户

发布于 2017-02-02 07:42:25

现在支持用户定义的数据类型。最新版本1.5.0.RELEASE使用Cassandra数据stax驱动程序3.1.3,因此它现在可以工作了。按照以下步骤使其工作

如何在Spring中使用UserDefinedType(UDT)特性:

  1. 我们需要使用的最新jar (1.5.0.RELEASE) 组:‘org.Spring cassandra work.data’,名称:‘spring cassandra’,版本:'1.5.0.RELEASE‘
  2. 确保它使用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
  3. 在Cassandra中创建用户定义的类型:类型名称应该与在POJO类中定义的相同

地址数据类型

代码语言:javascript
复制
CREATE TYPE address_type ( 
    id text, 
    address_type text, 
    first_name text, 
    phone text 
);
  1. 在Cassandra中,使用其中一个列创建列,作为UDT: 雇员表: 创建表employee( employee_id uuid,employee_name文本,地址冻结,主键(employee_id,employee_name) );
  2. 在域类中,定义带有注释-CassandraType和DataType的字段应该是UDT: @Table(" Employee ")公共类雇员{- othere字段- @CassandraType(type = DataType.Name.UDT,userTypeName = "address_type")私有地址;}
  3. 为用户定义的类型创建域类:我们需要确保用户定义的类型模式中的列名必须与域类中的字段名相同。 @UserDefinedType("address_type")公共类地址{ @CassandraType(type = DataType.Name.TEXT)私有字符串id;@CassandraType(type = DataType.Name.TEXT)私有字符串address_type;}
  4. 在Cassandra Config中,更改如下: @Bean public CassandraMappingContext mappingContext()抛出异常{ BasicCassandraMappingContext mappingContext =新BasicCassandraMappingContext();mappingContext.setUserTypeResolver(新SimpleUserTypeResolver(群集().getObject(),cassandraKeyspace));返回mappingContext;}
  5. 用户定义的类型应该在任何地方都具有相同的名称。如:
代码语言:javascript
复制
- @UserDefinedType("address\_type")
- @CassandraType(type = DataType.Name.UDT, userTypeName = "address\_type")
- CREATE TYPE address\_type

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34753799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档