java - una - No hay suficientes bytes para leer el valor del componente utilizando columnas compuestas con el cliente Astyanax
seleccionar celda jtable java (1)
Cuando crea ColumnFamily, los argumentos son para columnName, rowKey serializer y column name serializer. El serializador de tipo de columna (complexTypeSerializer) solo se usa en putColumn. Deberías:
ColumnFamily columnFamily = new ColumnFamily(columnFamilyName, StringSerializer.get(), StringSerializer.get());
ya que no está utilizando nombres de columnas compuestas, sino valores compuestos de columnas.
Estoy escribiendo para insertar en Columna compuesta en la familia de columnas de Cassandra utilizando el cliente de Astyanax. Debajo está mi familia de columnas en 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;
Estoy esperando después de la inserción, se verá así
user-id column1
123 (Column1-Value Column1-SchemaName LastModifiedDate)
A continuación está mi código principal de 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");
}
Debajo está mi clase 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;
}
}
A continuación se muestra mi método upsertCompositeAttributes
en mi 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) {
}
}
Ahora estoy obteniendo la siguiente excepción-
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
Debajo está mi clase 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());
}
Antes que nada, ¿mi familia de columna es correcta o no?
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;
Debajo está mi requerimiento por nuestro caso de uso-
user-id column1 column2 column3
123 (Column1-Value Column1-SchemaName LMD) (Column2-Value Column2-SchemaName LMD) (Column3-Value Column3-SchemaName LMD)
Para cada ID de usuario, almacenaremos la columna 1 y su valor, y ese valor almacenará estas tres cosas siempre:
(Column1-Value Column1-SchemaName LMD)
En mi ejemplo anterior, he mostrado solo tres columnas pero podría tener más columnas.
Estoy ejecutando Cassandra 1.2.9