1
votes

I am trying to access Cassandra @ localhost using a standalone main() method. The main() method uses DataStax driver and CassandraOperations class from spring-data-cassandra module. CassandraOperation's queryForObject() method always return the primary key instead of Entity Object.

I am just using the code example given in the Spring Data Documentation.

Apache-Cassandra version : 2.1.2
Spring-Data-Cassandra version : 1.2.0.RELEASE

Entity Class :
import org.springframework.data.cassandra.mapping.PrimaryKey;
import org.springframework.data.cassandra.mapping.Table;

@Table
public class Person {

    @PrimaryKey
    private String id;

    private String name;
    private int age;

    public Person(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
}

Client Code:

public class CassandraApp {

    private static final Logger LOG = LoggerFactory.getLogger(CassandraApp.class);

    private static Cluster cluster;
    private static Session session;

    public static void main(String[] args) {

        try {

            cluster = Cluster.builder().addContactPoints(InetAddress.getLocalHost()).build();

            session = cluster.connect("person");

            CassandraOperations cassandraOps = new CassandraTemplate(session);

            cassandraOps.insert(new Person("1234567890", "David", 40));

            Select s = QueryBuilder.select().from("person");
            s.where(QueryBuilder.eq("id", "1234567890"));

            System.out.println(cassandraOps.queryForObject(s, Person.class).getId());

            cassandraOps.truncate("person");

        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

    }
}

Runtime exception:

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to com.prashanth.ts.entity.Person at com.prashanth.ts.client.CassandraApp.main(CassandraApp.java:40) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

I am new to Spring Data. Any one can help me identify what I am doing wrong here.

I also tried removing the QueryBuilder and passing a simple query String like "select * from person" to the queryForObject() methodd

Note : The insert operation is working perfectly.

3

3 Answers

1
votes

I was able to make it work using selectOne method instead of queryForObject.

LOG.info(cassandraOps.selectOne(s, Person.class).getId());
0
votes

Judging by documentation here, you need to add one more method(all) for QueryBuilder:

  Select s = QueryBuilder.select().all().from("person");

On a side note, you are using spring-data-cassandra but you are not utilizing it's best features which would make your code much simpler.

0
votes

I can see where the OP could have gotten confused here. Finding no code extension provided by Eclipse I went to the org.springframework.data.cassandra.core Interface CassandraOperations documentation. There is no queryForObject documented so unless someone can explain otherwise

LOG.info(cassandraOps.queryForObject(s, Person.class).getId());

is just bad code. I tried to find the correct usage of queryForObject but all the searches took me back to the example in question which seems to have originated in 2008. Who knows, at one point it may have worked. The OP was trying to use Cassandra Operations to extract information from "s". I liked the idea of Amit T and got something working. I had my own class using Company instead of Person but the idea is the same.

try { 

               cluster = Cluster.builder().withoutMetrics().addContactPoints(InetAddress.getByName("192.168.1.5") ).build(); 

               session = cluster.connect("rant"); 

               CassandraOperations cassandraOps = new CassandraTemplate(session); 

               cassandraOps.insert(new Companies("name1", "user", "category", "first", "last", "city", "state", "zipcode", "phone", "email",  
                       "addr1c", "adddr2c", "cityc", "statec", "zipcodec", "phonec", "emailc", "website", 0.0, 0.0, 
                       0, 0, "pr", 0, "text"));

               Select s = QueryBuilder.select().from("companies"); 
               s.where(QueryBuilder.eq("company_company", "name1")); 

//             LOG.info(cassandraOps.queryForObject(s, Companies.class).getId()); 
               LOG.info(cassandraOps.selectOne(s, Companies.class).CompanyInformation());

               cassandraOps.truncate(Companies.class);  // empties the table

              } catch (UnknownHostException e) { 
                  e.printStackTrace(); 
              } 

             } 

I also created my own CompanyInformation() just as an exercise.

public String CompanyInformation() {
   System.out.println("Company Information " + this.company_company);
   return this.company_userid;
}  

The output was as expected.

19:35:24.456 [cluster1-nio-worker-2] DEBUG com.datastax.driver.core.Connection - Connection[/192.168.1.5:9042-2, inFlight=1, closed=false] Keyspace set to rant
Company Information name1      <== from CompanyInformation()
19:35:24.483 [main] INFO com.androidcommand.app.SpringRbsApplication - user <== from LOG.Info
19:35:24.485 [main] DEBUG org.springframework.data.cassandra.core.cql.CqlTemplate - Executing CQL Statement [TRUNCATE companies;]