Cassandra Accessor / Mapper not mapping udt field

北城余情 提交于 2019-12-12 03:53:48

问题


I am using datastax cassandra 3.1.2. I have created the following table in cassandra and inserted a record.

CREATE TYPE memory ( capacity text );
create TABLE laptop ( id uuid primary key, model text, ram frozen<memory> );
select * from laptop ;

 id                                   | model         | ram
--------------------------------------+---------------+-------------------
 e55cba2b-0847-40d5-ad56-ae97e793dc3e | Dell Latitude | {capacity: '8gb'}

When I am trying to fetch the capacity field from frozen type memory in Java using Cassandra Accessor with the below code:

this.cluster = Cluster.builder().addContactPoint(node).withPort(port).build();
session = cluster.connect();
MappingManager manager = new MappingManager(session);
LaptopAccessor laptopAccessor = manager.createAccessor(LaptopAccessor.class);
Result<Laptop> cp = laptopAccessor.getOne(UUID.fromString("e55cba2b-0847-40d5-ad56-ae97e793dc3e"));
System.out.println(cp.one());

It is giving ram datapoint itself is null.

id = null model = null ram = null

I was expecting that the mapper would create ram instance while mapping and map capacity field into it and return the Laptop bean.

I have the following Accessor interface:

@Accessor
interface LaptopAccessor {
   @Query("SELECT ram.capacity FROM user_info.laptop where id=?")
   Result<Laptop> getOne(UUID id);
}

I have the following java beans for the above table.

@Table(keyspace = "user_info", name = "laptop")
public class Laptop {

    private UUID id;
    private String model;
    private Memory ram;

    @PartitionKey
    public UUID getId() {
        return id;
    }

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


    public String getModel() {
        return model;
    }


    public void setModel(String model) {
        this.model = model;
    }

    @Frozen
    public Memory getRam() {
        return ram;
    }


    public void setRam(Memory ram) {
        this.ram = ram;
    }

    @Override
    public String toString() {
        return "id = " + id + " model = " + model + " ram = " + ram;
    }

}

@UDT(keyspace = "user_info", name = "memory")
public class Memory {

    private String capacity;

    @Field
    public String getCapacity() {
        return capacity;
    }


    public void setCapacity(String capacity) {
        this.capacity = capacity;
    }

    @Override
    public String toString() {
        return "capacity = " + capacity ;
    }

}

The code works fine when I change the query to retrieve entire ram UDT. Could somebody please tell that why the mapper doesn't work when I select some field from the udt in the query?

Doesn't cassandra support this? Any workaround to fetch the UDT fields?


回答1:


I think the issue is the return type on your accessor:

@Accessor
interface LaptopAccessor {
   @Query("SELECT ram.capacity FROM user_info.laptop where id=?")
   Result<Laptop> getOne(UUID id);
}

Since your query is only selecting ram.capacity, all the driver is getting back is a Row with a single column that is a String with a name of ram.capacity which does not map to any field in Laptop.

Instead, since it looks like all you want is the 1 row matching that query, you could change your Accessor to:

@Accessor
interface LaptopAccessor {
   @Query("SELECT ram.capacity FROM user_info.laptop where id=?")
   ResultSet getOne(UUID id);
}

The accessor now returns a ResultSet for which you can call one().getString(0) to get the capacity back. It's not ideal if you don't want to deal with ResultSet directly, but works well.

You shouldn't really need the whole Laptop object anyways since all you are requesting is a field of a UDT right?



来源:https://stackoverflow.com/questions/42144862/cassandra-accessor-mapper-not-mapping-udt-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!