Denn0
Denn0

Reputation: 397

Using complex data structures in spring data for Cassandra

I'm working on setting up a DAO for Cassandra in spring.

Now I have a question regarding using composite classes multiple times in an object.

I have this class Setting:

@Table(value = "settings")
public class Setting  {

    @PrimaryKey
    private User owner;

    @Column("key")
    private String key;

    @Column("value")
    private String value;

    @Column("updated_by")
    private User updatedBy;
}

And the class User:

@PrimaryKeyClass
public class User implements Serializable{

    @PrimaryKeyColumn(name = "userId", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
    private String id;

    @PrimaryKeyColumn(name = "userIdType", ordinal = 1, type = PrimaryKeyType.PARTITIONED)
    private String idType;
}

So I'm using the class User twice. Once as primary key "owner" and once as "updatedBy".

When using this in the CassandraOperations classes, it works fine as the primary key, but not again as another column.

It complains about column name userId already being used. Makes sense. So how can I make this work?

I could use UserDefined Types perhaps?

CREATE TYPE test_keyspace.user (
    id text,
    id_type text
);

But how can I do that from java Annotations?

Or, how can I reuse the same class otherwise? Considering the relatively simple data structures in Cassandra, I am ok with flattening the User class as a single String like idType.id too.

Thanks for any help!

Upvotes: 1

Views: 2084

Answers (1)

Denn0
Denn0

Reputation: 397

Ok, found it here, answered by denzal.

My classes now look like:

@Table("settings")
public class Setting  {

    @PrimaryKeyColumn(name = "owner", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
    @CassandraType(type = DataType.Name.UDT, userTypeName = "user_type") 
    private User owner;

    @PrimaryKeyColumn(name = "key", ordinal = 1, type = PrimaryKeyType.CLUSTERED)
    @CassandraType(type = DataType.Name.TEXT) 
    private String key;

    @CassandraType(type = DataType.Name.TEXT) 
    private String value;

    @CassandraType(type = DataType.Name.UDT, userTypeName = "user_type") 
    private User lastUpdatedBy;
}

And User Class:

@UserDefinedType("user_type") 
public class User implements Serializable{

    @CassandraType(type = DataType.Name.TEXT) 
    private String id;

    @CassandraType(type = DataType.Name.TEXT)
    private IdType idType;

}

Works nicely.

Upvotes: 4

Related Questions