2017-02-09 2 views
0

私はdatastax cassandra 3.1.2を使用しています。私はcassandraに次の表を作成し、レコードを挿入しました。カサンドラアクセッサ/マッパーマッピングフィールドudtなし

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

私は以下のコードでカサンドラアクセサを使用してJavaで凍結されたタイプのメモリから容量フィールドを取得しようとしています:

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

それはデータポイント自体がnullであるラムを与えています。

マッパーがマップして容量フィールドをマッピングしてラップトップBeanを返す間に、マッパーがramインスタンスを作成すると予想していました。

私は、次のアクセサインターフェースを持っている:

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

私は上記の表のための次のJava Beanを持っています。

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

} 

ram UDT全体を取得するようにクエリを変更すると、コードは正常に機能します。クエリ内のudtからフィールドを選択すると、マッパーが機能しない理由を教えてください。

cassandraはこれをサポートしていませんか? UDTフィールドを取得するための回避策はありますか?

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

クエリのみram.capacityを選択されているので、すべてのドライバーが戻ってきていることとStringある単一の列と行は次のとおりです。

答えて

1

私は問題があなたのアクセサの戻り値の型だと思いますの名前はLaptopのいずれのフィールドにもマッピングされません。

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

アクセサ今あなたが取得するone().getString(0)を呼び出すことができたためResultSetを返します。それはあなたが望むすべてがそのクエリに一致する1行であるように、あなたはAccessorにを変更することができます見えますので、その代わり

、キャパシティバック。直接ResultSetに対処したくない場合は理想的ではありませんが、うまく機能します。

あなたが要求しているものはすべてUDTの権利のフィールドなので、実際にはLaptopオブジェクト全体は必要ありませんか?

+0

回答ありがとうございます。しかし、私のアクセサの戻り値の型は一般的なもので、インターフェイスには完全なラップトップオブジェクトとフェッチャーの部分(非同期)を返す他のいくつかのクエリがあります。私はいつもコレクションのように集めます results = results.add(future.get()。one());だから、私はResultSetに直接働くことは私のケースでは特別な場合、私は複数のデータ型を持つUDTフィールドのみを返すようなクエリを持っている場合には機能しないと思う。 – Ravi

+0

私はudtから取得したいすべてのフィールドをテーブルレベルで移動したり、テーブルレベル(容量)のプレースホルダを定義して、SELECT ram.capacityのようなクエリを起動できるようにする予定です。from user FROM user_info.laptop where id =? ' – Ravi

+0

次のテーブル構造を持っている場合: CREATE TABLE user_info。employees_with_address( id uuid PRIMARY KEY、 complete_addressリスト>) plain_addressをプレーンなクエリで取得すると、以下のような処理をしてList Frozen UDTを解析する必要があります。 行r = rsf.get()。one(); r.getList(r.getColumnDefinitions()。getName()、CompleteAddress.class); 汎用性を持たせたい場合、Definitionを使用してCompleteAddress.class型を取得するにはどうすればよいですか? – Ravi

関連する問題