2014-11-08 78 views
4

springdatacassandra如何支持由Cassandra在POJO中提供的用戶定義數據類型?我正在爲UDT尋找註釋。Spring數據的UDT註解Cassandra

+0

類似的問題在這裏的答案:http://stackoverflow.com/questions/38862460/user-defined-type-with-spring-data-cassandra/42036202#42036202 – denzal 2017-02-17 05:40:33

回答

1

Spring數據cassandra最新版本(1.2.0.BUILD-SNAPSHOT)取決於datastax驅動程序2.0.4,其中自從datastax驅動程序2.1.x起支持UDT。

您可以嘗試覆蓋datastax驅動程序到2.1.x以使用2.1驅動程序提供的最新功能。

+0

Thanku @shatk回覆。這是我正在尋找的。 – dwingle 2014-11-08 11:49:58

+1

只是爲了更清楚一點:在這一點上,DataStax文檔中看到的'@ UDT'和其他映射註釋('com.datastax.driver.mapping.annotations。*')不受spring-data-cassandra支持。這些註釋由工件'cassandra-driver-mapping'提供。使用DataStax註釋註解的類需要通過'com.datastax.driver.mapping.Mapper'持久化,請參閱http://www.datastax.com/documentation/developer/java-driver/2.1/java-driver/reference/ mappingUdts.html – 2015-02-12 14:45:05

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

是需要的,但總的來說它不起作用,spring數據cassandra不支持UDT映射。

看到這裏的細節: https://jira.spring.io/browse/DATACASS-172

我面對這個問題,調試過程向我展示了春天的數據卡珊德拉支票 @Table,@Persistent或僅@PrimaryKeyClass註釋,並提出在另一種情況下

異常

> 調用init方法失敗;嵌套的例外是org.springframework.data.cassandra.mapping.VerifierMappingExceptions: 卡桑德拉實體必須有@Table,@Persistent或@PrimaryKeyClass註釋

但我找到了解決辦法。 我想出了讓我管理包含UDT的實體和不包含UDT的實體的方法。在我的應用程序中,我使用spring cassandra數據項目以及使用直接datastax核心驅動程序。不包含UDT對象的存儲庫使用spring cassanta數據方法,包含UDT的對象使用定製存儲庫。 自定義庫使用datastax映射,與他們同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; 
    } 
} 

和Spring數據相關的回購協議是resonsible用於管理沒有實體包括UDT對象如下所示:

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對象:

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和僅使用彈簧數據卡桑德拉框架:

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

注意只使用數據STAX annatation

POJO的,下面的實體使用不同的註釋:

@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不應該駐留在不同的封裝)原因Spring配置尋找基礎包與回購:

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