Skip to content

Cassitory using Entity Mappers

Cael edited this page Jun 28, 2019 · 6 revisions

Indroduction

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.

Steps to use the library

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'

Step 1: Create your Cassandra entities

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.

Step 2: Create your DTO.

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
}

Finally

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);

Annotations spec

NOTE: you can define the destinationPackage field in CassandraEntity where you want to generate all the classes.

@CassitoryEntity

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

@Mapping

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;