Spring data Cassandra 2.0 Select BLOB column returns incorrect ByteBuffer data -


context: spring data cassandra official 1.0.2.release maven central repo, cql3, cassandra 2.0, datastax driver 2.0.4

background: cassandra blob data type mapped java bytebuffer.

the sample code below demonstrates won't retrieve correct bytes using select next equivalent insert. data retrieved prefixed numerous garbage bytes looks serialization of entire row. older post relating cassandra 1.2 suggested may have start @ bytebuffer.arrayoffset() of length bytebuffer.remaining(), arrayoffset value 0.

i discovered spring-data-cassandra 2.0.0. snapshot cassandraoperations api different, , package name too: org.springdata... versus org.springframework...

help in fixing welcome.

in mean time looks have encode/decode base64 binary data to/from text data type column.

--- here simple table cql meta data use -------------

create table person (   id text,   age int,   name text,   pict blob,   primary key (id) ) ; 

--- follows simple data object mapped cql table ---

package org.spring.cassandra.example;   import java.nio.bytebuffer; import org.springframework.data.cassandra.mapping.primarykey;  import org.springframework.data.cassandra.mapping.table;   @table  public class person {    @primarykey   private string id;    private int age;   private string name;   private bytebuffer pict;    public person(string id, int age, string name, bytebuffer pict) {    this.id = id; this.name = name; this.age = age; this.pict = pict;  }    public string getid() { return id; }   public string getname() { return name; }   public int getage() { return age; }   public bytebuffer getpict() { return pict; }    }   } 

--- , plain java application code inserts , retrieves person object --

package org.spring.cassandra.example;  import java.nio.bytebuffer;  import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; import org.springframework.data.cassandra.core.cassandraoperations;  import com.datastax.driver.core.resultset; import com.datastax.driver.core.row; import com.datastax.driver.core.querybuilder.querybuilder; import com.datastax.driver.core.querybuilder.select;  public class cassandraapp {      private static final logger logger = loggerfactory             .getlogger(cassandraapp.class);      public static string hexdump(bytebuffer bb) {         char[] hexarray = "0123456789abcdef".tochararray();         bb.rewind();         char[] hexchars = new char[bb.limit() * 2];         ( int j = 0; j < bb.limit(); j++ ) {             int v = bb.get() & 0xff;             hexchars[j * 2] = hexarray[v >>> 4];             hexchars[j * 2 + 1] = hexarray[v & 0x0f];         }         bb.rewind();         return new string(hexchars);     }      public static void main(string[] args) {          applicationcontext applicationcontext = new classpathxmlapplicationcontext("app-context.xml");          try {              cassandraoperations cassandraops = applicationcontext.getbean(                     "cassandratemplate", cassandraoperations.class);              cassandraops.truncate("person");             // prepare data             byte[] ba = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11, 0x22, 0x33, 0x44, 0x55, (byte) 0xaa, (byte) 0xcc, (byte) 0xff };             bytebuffer mypict = bytebuffer.wrap(ba);             string myid = "1234567890";             string myname = "mickey";             int myage = 50;              logger.info("we try id=" + myid + ", name=" + myname + ", age=" + myage +", pict=" + hexdump(mypict));              cassandraops.insert(new person(myid, myage, myname, mypict ));              select s = querybuilder.select("id","name","age","pict").from("person");             s.where(querybuilder.eq("id", myid));              resultset rs = cassandraops.query(s);             row r = rs.one();              logger.info("we got id=" + r.getstring(0) + ", name=" + r.getstring(1) + ", age=" + r.getint(2) +", pict=" + hexdump(r.getbytes(3)));          } catch (exception e) {             e.printstacktrace();         }      } } 

--- assuming have configured simple spring project cassandra explained @ http://projects.spring.io/spring-data-cassandra/

the actual execution yields (slide these logger traces see end):

[main] info org.spring.cassandra.example.cassandraapp - try id=1234567890, name=mickey, age=50, pict= 0001020304051122334455aaccff

[main] info org.spring.cassandra.example.cassandraapp - got id=1234567890, name=mickey, age=50, pict=8200000800000073000000020000000100000004000a6d796b657973706163650006706572736f6e00026964000d00046e616d65000d000361676500090004706963740003000000010000000a31323334353637383930000000066d69636b657900000004000000320000000e 0001020304051122334455aaccff

although insert looks correct in database itself, seen cqlsh command line:

cqlsh:mykeyspace> select * person;   id         | age | name   | pict ------------+-----+--------+--------------------------------  1234567890 |  50 | mickey | 0x0001020304051122334455aaccff  (1 rows) 

i had same problem have fortunately found solution. problem bytebuffer use confusing. try doing like:

bytebuffer bb = resultset.one().getbytes("column_name"); byte[] data = new byte[bb.remaining()]; bb.get(data); 

thanks sylvain's suggestion here: http://grokbase.com/t/cassandra/user/134brvqzd3/blobs-in-cql


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -