我正在使用Astyanax客户端插入Cassandra列族中的Composite Column。以下是我在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) {
}
}
现在我收到以下异常 -
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());
}
首先,我的专栏系列是否正确?
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 column2 column3
123 (Column1-Value Column1-SchemaName LMD) (Column2-Value Column2-SchemaName LMD) (Column3-Value Column3-SchemaName LMD)
对于每个user-id,我们将存储column1及其值,该值将始终存储这三个东西 -
(Column1-Value Column1-SchemaName LMD)
在上面的示例中,我只显示了三列,但可能有更多列。
我正在运行Cassandra 1.2.9
答案 0 :(得分:2)
创建ColumnFamily时,参数用于columnName,rowKey序列化程序和列名称序列化程序。列类型序列化程序(complexTypeSerializer)仅用于putColumn。你应该:
ColumnFamily columnFamily = new ColumnFamily(columnFamilyName, StringSerializer.get(), StringSerializer.get());
因为您没有使用复合列名称,而是使用复合列值。