-
Notifications
You must be signed in to change notification settings - Fork 0
Cassitory using Entity Mappers
If you are thinking or already using Cassandra annotations in your pojos and the ObjectMapper then this is the right way for you.
Cassitory gives you a way to generate your Repository reusing your Cassandra entities.
Cassitory is quite simple to use just following the steps and it will give you a Repository for your DTO ready to use in your application.
Add this dependency yo your grade.build
annotationProcessor 'uk.co.caeldev:cassitory:0.2.1'
First you create your Cassandra Entities mapping to your tables as you would do it normally. Eg. asumming that you have two tables, users and users_by_name. This would it mean two Cassandra entities more like this:
@Table(keyspace = "ks", name = "users",
readConsistency = "QUORUM",
writeConsistency = "QUORUM",
caseSensitiveKeyspace = false,
caseSensitiveTable = false)
public class User {
@PartitionKey
@Column(name = "user_id")
private UUID userId;
@Column(name = "name")
private String name;
@Column(name = "street")
private String street;
//WITH THE SETTERS AND GETTERS
}
@Table(keyspace = "ks", name = "users_by_name",
readConsistency = "QUORUM",
writeConsistency = "QUORUM",
caseSensitiveKeyspace = false,
caseSensitiveTable = false)
public class UserByName {
@PartitionKey(0)
@Column(name = "user_id")
private UUID userId;
@PartitionKey(1)
@Column(name = "full_name")
private String name;
@Column(name = "creation_date")
private LocalDate creationDate;
@Column(name = "address")
private String address;
//WITH THE SETTERS AND GETTERS
}
NOTE: for version 1, there a convention that, let say that your main table is USERS, and USERS_BY_NAME is derived the beans needs to have the same name of fields. Also all the getters and setters. I have some ideas to support more things but for version 1 it will be like this.
Cassitory works by using the DTO as placeholder for the data that you want to persist and it will hold how to map to the Cassandra entities.
You will have to use this annotations:
uk.co.caeldev.cassitory.entities.CassitoryEntity
uk.co.caeldev.cassitory.entities.Mapping
Following the eg. above this would looks like this.
@CassitoryEntity(target={UserByName.class, User.class})
class UserDto {
@Mapping(target={User.class, UserByName.class}, field="userId")
private String id;
@Mapping(target={UserByName.class}, field="creationDate")
private LocalDate creationDate;
@Mapping(target={User.class, UserByName.class})
private String name;
@Mapping(target={User.class}, field="street")
@Mapping(target={UserByName.class}, field="address")
private String address;
// GENERATE ALL THE GETTERS AND SETTERS
}
After you annotate your classes Cassitory will generate a Base Repository class per class annotated. the convention will be, for instance if your DTO class is UserDto... you will be able to find UserDtoBaseRespository.
MappingManager mappingManager;
UserDtoBaseRespository repository = new UserDtoBaseRespository(mappingManager);
NOTE: you can define the destinationPackage field in CassandraEntity where you want to generate all the classes.
Use this annotation to generate the a repository using Mapper Manager and Cassandra entities.
@CassitoryEntity(target={User.class})
class UserDto
There are few optional parameters like:
destinationPackage: where all the generated code will be using. By default is the the same package than the annotated class.
@CassitoryEntity(target={User.class}, destinationPackage="company.repositories")
class UserDto
consistencyLevel: set the consistency level for all the write operations whithin the repository. By default is QUORUM.
@CassitoryEntity(target={User.class}, consistencyLevel=ConsistencyLevel.ONE)
class UserDto
tracing: enable tracing option for all the write operations whithin the repository. By default is false.
@CassitoryEntity(target={User.class}, tracing=true)
class UserDto
Use this annotation to describe how to map a field in your Dto to the different Cassandra entities. As you can see there are a few ways to use Mapping annotation:
//Map the field to the classes User and Username and populate in //each of them the field name.
@Mapping(target={User.class, UserByName.class}, field="name")
private String name;
//Because the field name in this entity is the same than the ones in //the Cassandra entities you can omit the field value.
@Mapping(target={User.class, UserByName.class})
private String name;
//In the case where you have different field names in your Cassandra //entities you can do this
@Mapping(target={User.class}, field="name" )
@Mapping(target={UserByName.class}, field="fullname")
private String name;
//And last, you can combine both approaches
@Mapping(target={User.class}, field="name" )
@Mapping(target={UserByName.class, UserByAge.class}, field="fullname")
private String name;