Usando Cassandra com Spring Data no Easy-Cassandra
Autor: Otávio Gonçalves de Santana | Publicado: 2013-08-25T07:57:00-03:00





O Spring é um framework open source cujo o objetivo sempre foi facilitar a vida do desenvolvedor Java, começou com os recursos para injeção de dependência e hoje atua em diversas atividades triviais para um programador. Entre elas podemos citar a parte social com o Spring social no twitter, facebook, segurança com o Spring security além do já inversão de controle e inversão de dependência. O foco desse pequeno post é falar sobre o Spring Data e seu trabalho com o banco não relacional Cassandra.

O Spring-data é um pequeno módulo ou plugin do Spring e tem como objetivo auxiliar nos processos triviais de persistência criando uma camada entre a base onde se encontra as informações e o seu código java. Dessa maneira é possível, efetuar ações na base, usando como estrutura para as informações, o POJO (simples e velho objetos em java). Dentro do Spring Data já existem diversos tipo de base de informações.


Bancos Relacionais com JPA e JDBC
BigData com Apache Hadoop
Data-Grid com GermFire
HTTP com Rest
NOSQL com MongoDB, Neo4J, Redis e Hbase



Uma das grandes vantagem do Spring Data é ser filho do Spring. Ele não precisa de um servidor Java EE, ou seja, ele pode rodar em um simples contêiner como o tomcat ou mesmo rodar sem o auxílio do servidor. Sua injeção funciona com auxílio de um arquivo xml, mas não necessariamente toda configuração é feita por lá, existem várias anotações que podem ajudar o desenvolvedor, no entanto, cabe apenas ao mesmo saber em qual momento é mais adequado usar cada um deles.

Com esse foco o Spring Data Cassandra tem o foco de criar uma camada de alto nível para o nosql Cassandra, assim é possível com estruturas de POJOs estabelecer uma conexão no banco e realizar as operações CRUD, tudo isso sem abrir mão da estrutura de dados já conhecida pelo desenvolvedor Java. O Spring Data Cassandra ainda não foi fechada, mas o Easy-Cassandra já possui integração com Spring, agora é possível utilizá-lo com a injeção de dependências do framework Java mais famoso do mundo.
A aplicação será realmente bastante simples seu objetivo será apenas criar uma informação e armazenar no banco, em seguida recuperar pelo id. O primeiro passo será a criação da entidade pessoa, ela terá os campos id, nome e ano, conforme mostra a tabela número1.



@Entity(name = "person") 
public class Person implements Serializable { 

    @Id 
    private UUID id; 
     
    @Index 
    @Column(name = "name") 
    private String name; 
    
    @Column(name = "born") 
    private Integer year;
//getter and setter

}

Simples Pojo da Classe pessoa

Como pode ser visto os campos são anotados via JPA 2.0, o segundo passo é a criação do xml, é nele que conterá as configurações do banco de dados (host, porta, keyspace padrão, etc.). O próximo passo é a configuração e criação da fábrica de conexões para o Cassandra dentro do spring, isso é, o host, porta e o keyspace padrão, e as classes que serão mapeadas como mostra no arquivo xml abaixo.


<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

 

 
 
 
  
   org.javabahia.cassandra.spring.entity.Person
  
 
 


 






Configuração do Spring-Data, informando as configurações do Banco (host, porta, nesse caso a padrão, e o keySpace) além de criar o Template Cassandra

Com a fábrica de conexões do cassandra é possível retornar uma sessão, a via de comunicação do Cassandra com a aplicação Java, além disso será criado o CassandraTemplate, uma api de alto nível que consegue realizar a comunicação Cassandra sua aplicação a partir de um simples POJO, desse modo é possível realizar a operação CRUD de uma maneira bastante simples, o código abaixo mostra a  interface do Cassandra template.



public interface CassandraTemplate{ 
   
     &lt;T&gt; T save(T entity); 
     
     &lt;T&gt; Iterable&lt;T&gt; save(Iterable&lt;T&gt; entities); 
     
     &lt;T&gt; void delete(T entity); 
     
     &lt;T&gt; void delete(Iterable&lt;T&gt; entities); 
     
     &lt;K&gt; void delete(K key, Class&lt;?&gt; entity); 
     
     &lt;K,T&gt; void delete(Iterable&lt;K&gt;  keys, Class&lt;T&gt; entity); 

     &lt;T&gt; void deleteAll(Class&lt;T&gt; entity); 
     
     &lt;T&gt; T update(T entity); 
     
     &lt;T&gt; Iterable&lt;T&gt; update(Iterable&lt;T&gt; entities); 
     
     &lt;T,K&gt; T findOne(K key, Class&lt;T&gt; entity); 
     
     &lt;T,K&gt; List&lt;T&gt; findAll(Iterable&lt;K&gt; keys, Class&lt;T&gt; entity); 
     
     &lt;T&gt; List&lt;T&gt; findAll(Class&lt;T&gt; entity); 
     
     &lt;T,I&gt; List&lt;T&gt; findByIndex(String columnName,I index,Class&lt;T&gt; entity); 
     
     &lt;K,T&gt;boolean exist(K key, Class&lt;T&gt; entity); 

     void executeUpdate(String query); 

Operações que podem ser realizadas com o seu Objeto

Além do CassandraTemplate existe o CassandraRepository, essa classe abstrata implementa o CrudRepository do SpringData, com ela é necessário apenas implementar o método que retornará o CassandraTemplate, conforme mostra a tabela abaixo.


@Repository("personRepository")
public class PersonRepository extends CassandraRepository&lt;Person, UUID&gt;{

 
 @Autowired
 private CassandraTemplate cassandraTemplate;
 
 @Override
 protected CassandraTemplate getCassandraTemplate() {
  return cassandraTemplate;
 }

}


Criando o repositório para a classe Person


Como o CassandraReporitory implementa a classe base de operações do Spring todas as suas operações estarão disponíveis para serem utilizadas com o Cassandra.


public interface CrudRepository&lt;T, ID extends Serializable&gt; extends Repository&lt;T, ID&gt; { 
 &lt;S extends T&gt; S save(S entity); 

 &lt;S extends T&gt; Iterable&lt;S&gt; save(Iterable&lt;S&gt; entities); 

 T findOne(ID id); 

 boolean exists(ID id); 

 Iterable&lt;T&gt; findAll(); 

 Iterable&lt;T&gt; findAll(Iterable&lt;ID&gt; ids); 

 long count(); 

 void delete(ID id); 

 void delete(T entity); 
 void delete(Iterable&lt;? extends T&gt; entities); 

 void deleteAll(); 
}

Interface CrudRepository do Spring Data que é implementada pela classe abstrata CassandraRepository


Realizado as configurações o próximo passo é executar o projeto como mostra o código a seguir:


public class App 
{
    public static void main( String[] args )
    {
     @SuppressWarnings("resource")
  ApplicationContext ctx = new GenericXmlApplicationContext("SpringConfig.xml");
     
     PersonRepository personService=ctx.getBean(PersonRepository.class);
     
     UUID uuid=UUID.randomUUID();
     Person person=new Person();
     person.setId(uuid);
     person.setName("Otávio Santana");
     person.setYear(25);
     
     personService.save(person);
     
     
     Person otavio=personService.findOne(uuid);
     System.out.println(otavio.getName());
     
     
    }
}


Rodando o Simples Projeto, salvando e recuperando a informação

Com isso foi demonstrado o conceito do Spring Data e o seu funcionamento com o Cassandra utilizando o Easy-Cassandra, o intuito criar uma interface padrão para que todos os modelos de persistência a utilizem dentro do Spring é um grande e importante passo para utilizar uma nova base ou modelo de dados não haja impacto dentro do Spring, mas é muito importante salientar que mesmo que vários bancos utilizem essa interface é importante considerar uma nova modelagem, já que diferente dos bancos relacionais, a mudança de um banco NOSQL pode significar a mudança estrutura de armazenamento.



Links:

 Spring Data: http://www.springsource.org/spring-data
 Easy-Cassandra: http://otaviojava.github.io/Easy-Cassandra/
 Exemplo: https://github.com/otaviojava/Easy-Cassandra-samples