spiralarchitect
spiralarchitect

Reputation: 910

Cassandra - unable to parse list of Tuple with Java driver

I am trying to access Tuple data structure I have stored in Cassandra with Mapper. But, I am unable to. I haven't found any example online.

This is the table and data I have created.

cqlsh:test> CREATE TABLE test.test_nested (id varchar PRIMARY KEY, address_mapping list<frozen<tuple<text,text>>>);
cqlsh:test> INSERT INTO test.test_nested (id, address_mapping) VALUES ('12345', [('Adress 1', 'pin1'), ('Adress 2', 'pin2')]);
cqlsh:test>
cqlsh:test> select * from test.test_nested;

id    | address_mapping
-------+----------------------------------------------
12345 | [('Adress 1', 'pin1'), ('Adress 2', 'pin2')]

(1 rows)

My mapped class(using lombok for builder, getter, setter):

@Builder
@Table(keyspace = "test", name = "test_nested")
public class TestNested {

    @PartitionKey
    @Column(name = "id")
    @Getter
    @Setter
    private String id;

    @Column(name = "address_mapping")
    @Frozen
    @Getter
    @Setter
    private List<Object> address_mapping;
}

My Mapper class: public class TestNestedStore {

private final Mapper<TestNested> mapper;

public TestNestedStore(Mapper<TestNested> mapper) {
    this.mapper = mapper;
}


public void insert(TestNested userDropData) {
    mapper.save(userDropData);
}


public void remove(String id) {
    mapper.delete(id);
}

public TestNested findByUserId(String id) {
    return mapper.get(id);
}

public ListenableFuture<TestNested> findByUserIdAsync(String id) {
    return mapper.getAsync(id);
}
}

I am trying to access data in a test method as follows:

    @Test
public void testConnection2(){

    MappingManager manager = new MappingManager(scyllaDBConnector.getSession());
    Mapper<TestNested> mapper = manager.mapper(TestNested.class);

    TestNestedStore testNestedStore = new TestNestedStore(mapper);

    ListenableFuture<TestNested> fut = testNestedStore.findByUserIdAsync("12345");
    Futures.addCallback(fut, new FutureCallback<TestNested>() {

        @Override
        public void onSuccess(TestNested testNested) {

        }

        @Override
        public void onFailure(Throwable throwable) {

            System.out.println("Call failed");
        }
    });

}

Bit, I am unable to access the tuple. I get this error:

java.lang.IllegalArgumentException: Error while checking frozen types on field address_mapping of entity com.example.model.TestNested: expected List to be not frozen but was frozen

at com.datastax.driver.mapping.AnnotationChecks.validateAnnotations(AnnotationChecks.java:73)
at com.datastax.driver.mapping.AnnotationParser.parseEntity(AnnotationParser.java:81)
at com.datastax.driver.mapping.MappingManager.getMapper(MappingManager.java:148)
at com.datastax.driver.mapping.MappingManager.mapper(MappingManager.java:105)

I have also tried with private List<TupleValue> address_mapping;. But of no use!

How do I access Tuple values through object mapper of cassandra?

Upvotes: 3

Views: 1482

Answers (2)

sudhir behera
sudhir behera

Reputation: 11

For defining the cassandra datatype of

map<text,frozen<tuple<text,text,int,text>>>

in java entity class mention the datatype as,

import com.datastax.driver.core.TupleValue;

@FrozenValue

private Map<String,TupleValue> event_driven;

Upvotes: 1

Duarte Nunes
Duarte Nunes

Reputation: 852

You define address_mapping as list<frozen<tuple<text,text>>>, that is, a list of frozen tuple values. To communicate this to the MappingManager, you can use the @FrozenValue attribute.

TestNested should look like:

@Builder
@Table(keyspace = "test", name = "test_nested")
public class TestNested {
    ...

    @Column(name = "address_mapping")
    @Frozen
    @Getter
    @Setter
    @FrozenValue
    private List<Object> address_mapping;
}

Upvotes: 2

Related Questions