使用Astyanax插入复合列时出现InvalidRequestException

时间:2013-09-20 04:24:09

标签: java cassandra astyanax column-family

我正在使用Astyanax客户端插入Cassandra列族中的Composite Column。每列都是一个复合列,意味着它的值将由我的ComplexType类中显示的三个值组成。以下是我在Cassandra的专栏。

create column family USER_DATA
with key_validation_class = 'UTF8Type'
and comparator = 'CompositeType(UTF8Type,UTF8Type,DateType)'
and default_validation_class = 'UTF8Type'
and gc_grace = 86400;

插入后我期待它看起来像这样。 (如果我的上述专栏系列不适合我的以下用例,请告诉我。)

user-id   column1
123      (Column1-Value  Column1-SchemaName  LastModifiedDate)

以下是我的java主要代码 -

public static void main(String[] args) {

    ComplexType ct = new ComplexType();
    ct.setVal1("Hello");
    ct.setVal2("World");
    ct.setTimestamp(System.currentTimeMillis());

    // e1 is the column-name and ct is its composite-value.
    attributesMap.put("e1", ct);

    clientDao.upsertCompositeAttributes("123", attributesMap, "USER_DATA");
}

下面是我的ComplexType类 -

public static class ComplexType {
    @Component(ordinal = 0)
    String val1;

    @Component(ordinal = 1)
    String val2;

    @Component(ordinal = 2)
    long timestamp;


    public String getVal1() {
        return val1;
    }
    public void setVal1(String val1) {
        this.val1 = val1;
    }
    public String getVal2() {
        return val2;
    }
    public void setVal2(String val2) {
        this.val2 = val2;
    }
    public long getTimestamp() {
        return timestamp;
    }
    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }
}

以下是我upsertCompositeAttributes中的DAOImpl class方法。

public void upsertCompositeAttributes(final String rowKey, final Map<String, ComplexType> ct, final String columnFamilyName) {

    try {
        AnnotatedCompositeSerializer<ComplexType> complexTypeSerializer = new AnnotatedCompositeSerializer<ComplexType>(ComplexType.class);

        ColumnFamily columnFamily = new ColumnFamily(columnFamilyName, StringSerializer.get(), StringSerializer.get());

        MutationBatch m = CassandraAstyanaxConnection.getInstance().getKeyspace().prepareMutationBatch();

        ColumnListMutation<String> mutation = m.withRow(columnFamily, rowKey);

        for (Map.Entry<String, ComplexType> entry : ct.entrySet()) {
          // entry.getKey() is the column name and entry.getValue() is its composite value.
            mutation = mutation.putColumn(entry.getKey(), entry.getValue(), complexTypeSerializer, null);
        }

        m.setConsistencyLevel(ConsistencyLevel.CL_ONE).execute();

    } catch (ConnectionException e) {

    } catch (Exception e) {

    }
}

以下是例外,我每次都从upsertCompositeAttributes方法获得。

com.netflix.astyanax.connectionpool.exceptions.BadRequestException: BadRequestException: [host=10.109.107.27(10.109.107.27):9160, latency=99(131), attempts=1]InvalidRequestException(why:Not enough bytes to read value of component 0)
    at com.netflix.astyanax.thrift.ThriftConverter.ToConnectionPoolException(ThriftConverter.java:159)
    at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:65)
    at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:28)
    at com.netflix.astyanax.thrift.ThriftSyncConnectionFactoryImpl$ThriftConnection.execute(ThriftSyncConnectionFactoryImpl.java:151)
    at com.netflix.astyanax.connectionpool.impl.AbstractExecuteWithFailoverImpl.tryOperation(AbstractExecuteWithFailoverImpl.java:69)
    at com.netflix.astyanax.connectionpool.impl.AbstractHostPartitionConnectionPool.executeWithFailover(AbstractHostPartitionConnectionPool.java:256)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl.executeOperation(ThriftKeyspaceImpl.java:485)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl.access$000(ThriftKeyspaceImpl.java:79)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl$1.execute(ThriftKeyspaceImpl.java:123)
    at com.cassandra.astyanax.CassandraAstyanaxClient.upsertCompositeAttributes(CassandraAstyanaxClient.java:167)
    at com.example.AstyanaxCompositeColumns.main(AstyanaxCompositeColumns.java:24)
Caused by: InvalidRequestException(why:Not enough bytes to read value of component 0)
    at org.apache.cassandra.thrift.Cassandra$batch_mutate_result.read(Cassandra.java:20833)
    at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:78)
    at org.apache.cassandra.thrift.Cassandra$Client.recv_batch_mutate(Cassandra.java:964)
    at org.apache.cassandra.thrift.Cassandra$Client.batch_mutate(Cassandra.java:950)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl$1$1.internalExecute(ThriftKeyspaceImpl.java:129)
    at com.netflix.astyanax.thrift.ThriftKeyspaceImpl$1$1.internalExecute(ThriftKeyspaceImpl.java:126)
    at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:60)
    ... 9 more

以下是我的CassandraAstyanaxConnection类 -

private CassandraAstyanaxConnection() {

    context = new AstyanaxContext.Builder()
    .forCluster(Constants.CLUSTER)
    .forKeyspace(Constants.KEYSPACE)
    .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
        .setPort(9160)
        .setMaxConnsPerHost(1000)
        .setSeeds("host:9160")
    )
    .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
        .setCqlVersion("3.0.0")
        .setTargetCassandraVersion("1.2")
        .setConnectionPoolType(ConnectionPoolType.ROUND_ROBIN)
        .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE))
    .withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
    .buildKeyspace(ThriftFamilyFactory.getInstance());

    context.start();
    keyspace = context.getEntity();

    emp_cf = ColumnFamily.newColumnFamily(
        Constants.COLUMN_FAMILY, 
        StringSerializer.get(), 
        StringSerializer.get());
}

我正在运行Cassandra 1.2.9和Astyanax 1.56.37

1 个答案:

答案 0 :(得分:1)

架构定义中的比较器元素描述列名,而不是列值。

如果是你的架构,Cassandra希望你给它一个带有3个组件的复杂密钥,但是得到一个简单的字符串并抱怨它:

  

没有足够的字节来读取组件0的值。