Spring Data Cassandra对UDT的注释

4

Spring Data Cassandra如何支持Cassandra提供的POJO中的用户定义数据类型? 我正在寻找UDT的注释。


类似的问题在这里有答案:https://dev59.com/lpnga4cB1Zd3GeqPcbR8#42036202 - denzal
2个回答

1
    <dependency>
        <groupId>com.datastax.cassandra</groupId>
        <artifactId>cassandra-driver-mapping</artifactId>
        <version>2.1.9</version>
    </dependency>

需要使用,但总体来说它不起作用,Spring Data Cassandra不支持UDT映射。
请在此处查看详细信息: https://jira.spring.io/browse/DATACASS-172 我遇到了这个问题,并且调试过程显示,Spring Data Cassandra仅检查@Table、@Persistent或@PrimaryKeyClass注释,并在另一种情况下引发异常。
但是我找到了解决方案。我想出了一种方法,可以让我管理包括UDT和不包括UDT的实体。在我的应用程序中,我同时使用spring cassandra数据项目和直接使用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 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 Data相关存储库如下:

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

我已经测试过这个解决方案,它百分之百有效。此外,我附上了我的POJO对象:
只使用data stax注释的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;   
}

使用Spring Data Cassandra框架,无需使用UDT的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和不包含UDT的对象进行工作。

一个重要的注意事项。使用UDT和不使用UDT的这两个仓库应该位于不同的包中,因为Spring配置会寻找带有仓库的基本包:

@Configuration
@EnableCassandraRepositories(basePackages = {
        "com.fyb.cassandra.repositories" })
public class CassandraConfig {
..........
}

1

Spring data cassandra最新版本(1.2.0.BUILD-SNAPSHOT)依赖于datastax driver 2.0.4,而UDT是从datastax driver 2.1.x开始支持的。

您可以尝试将datastax驱动程序覆盖为2.1.x,以使用2.1驱动程序提供的最新功能。


谢谢 @shatk 的回复。这正是我所需要的。 - dwingle
1
只是为了更清晰明确:@UDT 和其他映射注解(com.datastax.driver.mapping.annotations.*)在 DataStax 文档中看到的,到目前为止还不被 spring-data-cassandra 支持。这些注解由 artifact cassandra-driver-mapping 提供。使用 DataStax 的注解进行注释的类需要通过 com.datastax.driver.mapping.Mapper 进行持久化,请参见 http://www.datastax.com/documentation/developer/java-driver/2.1/java-driver/reference/mappingUdts.html。 - Michael Técourt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接