cassandra用户定义类型的InvalidTypeException

时间:2016-07-30 19:36:39

标签: java cassandra datastax-java-driver

当我从Cassandra DB读取用户数据时,我遇到了异常。我的Cassandra DB版本是2.1.14。

Exception in thread "main" com.datastax.driver.core.exceptions.InvalidTypeException: 
Column addresses is a map of class java.lang.String->class java.nio.ByteBuffer 
(CQL type map<varchar, 'org.apache.cassandra.db.marshal.UserType(ks_home_poc,61646472657373,737472656574:org.apache.cassandra.db.marshal.UTF8Type,
63697479:org.apache.cassandra.db.marshal.UTF8Type,7a69705f636f6465:org.apache.cassandra.db.marshal.Int32Type)'>), 
cannot be retrieve as a map of class java.lang.String->class com.home.cspoc.cassandra_poc.Address
    at com.datastax.driver.core.AbstractGettableData.getMap(AbstractGettableData.java:281)
    at com.datastax.driver.core.AbstractGettableData.getMap(AbstractGettableData.java:291)
    at com.home.cspoc.cassandra_poc.App.main(App.java:36)

下面是表格结构:

CREATE TABLE ks_home_poc.users (
  id uuid PRIMARY KEY,
  name text,  
  addresses map<text, frozen<address>>   
);  

CREATE TYPE ks_home_poc.address (
  street text,
  city text,
  zip_code int
);

insert into users
(
    id,addresses,name   
)
values
(
    now(),{'Home':{street:'1st street',city:'dubai',zip_code:97}},'test data'   
);

以下是Java代码:

import java.util.Map;

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;

public class App 
{
    public static void main( String[] args )
    {

        String serverIp ="xx.xx.xxx.xx";
        Cluster cluster = Cluster.builder()
                .addContactPoint(serverIp)
                .withPort(9042)                
                .build();
        Session session = cluster.connect("ks_home_poc");

        PreparedStatement selectStmt = session.prepare("select * from users;");
        ResultSet rs = session.execute(selectStmt.bind());

        for(Row row:rs){
            Map<String,Address> abc=row.getMap("addresses", String.class, Address.class);
        }

        //Mapper<Users> mapper = new MappingManager(session).mapper(Users.class);   

        session.close();
    }
}

import java.util.Map;
import java.util.UUID;

import com.datastax.driver.mapping.annotations.Column;
import com.datastax.driver.mapping.annotations.Frozen;
import com.datastax.driver.mapping.annotations.PartitionKey;
import com.datastax.driver.mapping.annotations.Table;

@Table(keyspace="ks_home_poc",name="users")
public class Users {

    @PartitionKey   
    private UUID id;

    @Frozen("map<text, frozen<Address>>")   
    private Map<String,Address> addresses;

    private String name;

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public Map<String, Address> getAddresses() {
        return addresses;
    }

    public void setAddresses(Map<String, Address> addresses) {
        this.addresses = addresses;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }   

}

import com.datastax.driver.mapping.annotations.Field;
import com.datastax.driver.mapping.annotations.UDT;

@UDT(keyspace = "ks_home_poc", name = "address")
public class Address {

    @Field(name="street")
    private String street;

    @Field(name="city")
    private String city;

    @Field(name="zip_code")
    private int zipCode;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public int getZipCode() {
        return zipCode;
    }

    public void setZipCode(int zipCode) {
        this.zipCode = zipCode;
    }

}

任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

您使用的是非常旧的驱动程序版本2.0.10,它不处理用户定义的类型。您需要升级到最新版本。我建议3.1.0。