Novos recursos - Easy-Cassadra 1.0.9 beta

Recentemente foi lançada a mais nova versão do Easy-Cassandra, o 1.0.9 beta, dentre as novidades estão nos usos de anotação e JPQL para o Cassandra.

Lançada a mais nova versão do framework que visa facilitar a persistência de objetos do apache Cassandra. Dentre as suas novidades está nas anotações, nessa versão estará usando as anotações do JPA. Outra novidade é o uso do recurso de JPQL, com isso se pode realizar querys com objetos e a ferramenta se encarregará de fazer a tradução para o Cassandra, para isso se utiliza a interface JCassandra que é estende de javax.persistence.Query. A expectativa é que aumentar ainda mais a produtividade para o desenvolvimento.

Listagem 1: exemplo usando o jpql no Easy-Cassandra

JCassandra jCassandra=persistence.createJCassandra("select * from Person"); List<Person> persons=jCassandra.getResultList();

Conforme dito acima as anotações foram adaptadas conforme mostra a tabela abaixo.

Easy-Cassandra 1.0.8 Easy-Cassandra 1.0.9 (Com JPA anotação)
org.easycassandra.annotations.ColumnFamilyValue javax.persistence.Entity
org.easycassandra.annotations.ColumnValue javax.persistence.Column
org.easycassandra.annotations.EmbeddedValue javax.persistence.Embedded
org.easycassandra.annotations.EnumeratedValue javax.persistence.Enumerated
org.easycassandra.annotations.KeyValue javax.persistence.Id
org.easycassandra.annotations.KeyValue equals true javax.persistence.GeneratedValue
org.easycassandra.annotations.IndexValue org.easycassandra.annotations.Index

tabela 1: relação entre as anotações da versão 1.0.8 e 1.0.9 com anotação jpa.

Também foi adicionado funcionalidade na anotação @Version do jpa, seu objetivo é verificar o tempo de inserção ou modificação do objeto.

Listagem 2: Usando a anotação version

@Entity(name = "autocount") public class Count implements Serializable { private static final long serialVersionUID = 3L; @Id @GeneratedValue private BigInteger id; @Column(name = "name") private String name; @Version private Long timeStampLong; @Version private Date timeStampDate; @Version private Calendar timeStampCalendar; //getter and setter } Para demonstrar novos recursos do framework será feito um exemplo de álbuns musicais que possa ser chamados em várias plataformas, para isso será usado web services. Para realizar esse exemplo será utilizado o java EE 6. Como o foco desse artigo não será o java EE 6, não entraremos em detalhes do mesmo. Após modelar e realizar as anotações com o jpa nossa classe ficará como mostra a listagem 3.

Listagem 3: classe com anotações jpa para o Easy-Cassandra

@XmlRootElement @Entity public class Album implements Serializable{ @Id private Long id; @Column(name="nameOfAlbum") private String name; @Column private String style; @Column private Calendar release; @Column private Double price; @Embedded private Artist artist; //getter and setter } @XmlRootElement public class Artist implements Serializable{ /** * name of the artist */ @Column(name="nameOfArtist") private String name; /** * was born */ @Column private String country; @Enumerated private Sex sex; //getter and setter } @XmlRootElement public enum Sex { MALE,FAMALE }

Uma vez pronta a classe de anotação o que será feito agora é recurso para o rest, uma coisa que vale salientar é que a inteface JCassandra estende da interface javax.persistence.Query, assim se pode estar a utilizando a interface Query (interessante para quem já está acostumado com o uso do jpa). Sendo que nem todas os métodos dessa interface estão implementados.

Assim realizando as chamadas com o novo recurso de jpql no Cassandra ficará de acordo mostra a tabela 5. Vale salientar como é feito para o Easy-Cassandra gerenciar a classe. Esse processo é realizado sem a necessidade do uso do xml, para isso é usado do método addFamilyObjec na Classe EasyCassandraManager. É necessário que a classe seja adicionada antes de se criar um jpql da respectiva classe. No nosso exemplo ele será feito na classe PersistenceManagement tão logo uma conexão para o cassandra for criada, como mostra a listagem 4.

Listagem 4: realizando um jpql no cassandra

@ApplicationScoped public class PersistenceManagement { @Produces private Persistence persistence; @Inject public void init(){ persistence=EasyCassandraManager.getPersistence("javabahia", "localhost", 9160); EasyCassandraManager.addFamilyObject(Album.class); } } @RequestScoped public class PersistenceService { @Inject private Persistence persistence; public List<Album> findAllAlbum() { Query query=persistence.createJCassandra (" select * from Album"); return query.getResultList(); } public Album findById(Long id) { Query query=persistence.createJCassandra (" select * from Album where id =:id"); query.setParameter("id", id); return (Album) query.getSingleResult(); } public boolean save(Album album) { return persistence.insert(album); } public void remove(Long id) { persistence.deleteByKeyValue(id, Album.class); } public String update(Long id, String name, String style, Double price,String nameOfArtis,String country) { StringBuilder query=new StringBuilder(); AuxQuery auxQuery=new AuxQuery(); String conecion=""; query.append("update Album set "); if(!isnull(name)){ query.append(conecion); query.append(" name =:name "); auxQuery.updatable=true; conecion=" , "; } if(!isnull(style)){ query.append(conecion); query.append(" style =:style "); auxQuery.updatable=true; conecion=" , "; } if(!isnull(price)){ query.append(conecion); query.append(" price =:price "); auxQuery.updatable=true; } if(!isnull(country)){ query.append(conecion); query.append(" artist.country =:country "); auxQuery.updatable=true; conecion=" , "; } if(!isnull(nameOfArtis)){ query.append(conecion); query.append(" artist.name =:artist "); auxQuery.updatable=true; } query.append(" where id =:id "); if(!auxQuery.updatable){ return "nothing is update"; } Query jCassandra=persistence.createJCassandra(query.toString()); if(!isnull(name)){ jCassandra.setParameter("name", name); } if(!isnull(style)){ jCassandra.setParameter("style", style); } if(!isnull(price)){ jCassandra.setParameter("price", price); } if(!isnull(nameOfArtis)){ jCassandra.setParameter("artist", nameOfArtis); } if(!isnull(country)){ jCassandra.setParameter("country", country); } jCassandra.setParameter("id", id); return jCassandra.executeUpdate()==1?"executed with sucess":" error in update "; } class AuxQuery{ boolean updatable=false; } private boolean isnull(Object object){ return object==null; } }

Uma vez implementados as querys será feito agora as chamadas agora será criado o recurso conforme mostra a tabela 6.

Listagem 5: criando um servidor rest com o JAX-RS

@Path("/album") @RequestScoped public class AlbumResource { @Inject private PersistenceService persistenceService; @GET @Produces(MediaType.TEXT_XML) public List<Album> getProdutos() { return persistenceService.findAllAlbum(); } @Path("") @GET @javax.ws.rs.Produces(MediaType.TEXT_XML) public Album getAlbum(@PathParam("id") long id) { return persistenceService.findById(id); } @Path("update/") @GET @javax.ws.rs.Produces(MediaType.TEXT_PLAIN) public String updateAlbum(@PathParam("id") Long id ,@QueryParam("name") String name,@QueryParam("style") String style,@QueryParam("price") Double price,@QueryParam("artist") String nameOfArtis,@QueryParam("country") String country) { return persistenceService.update(id,name,style,price,nameOfArtis,country); } @POST @Consumes(MediaType.TEXT_XML) @Produces(MediaType.TEXT_PLAIN) public String addAlbum(Album album) { boolean sucess=persistenceService.save(album); if(sucess){ return album.getName() + " added!"; } return album.getName() + " not added!"; } @Path("") @DELETE @Produces(MediaType.TEXT_PLAIN) public String removeAlbum(@PathParam("id") Long id) { persistenceService.remove(id); return "Album removed."; } }

Uma das maneiras de se realizar os testes é utilizando o poster, um plugin para o firefox, que estará disponível nos links. Com ele se poderá realizar todos os testes, inclusive aqueles que envolvam o post e remove. É possível realizar alguns testes já no navegador:

http://localhost:8080/AlbumServer/resources/album/ Lista de álbum
http://localhost:8080/AlbumServer/resources/album/1 Lista o álbum com o id 1
http://localhost:8080/AlbumServer/resources/album/n Lista o álbum com o id N
http://localhost:8080/AlbumServer/resources/album/update/12?name=%20Nome%20do%20Album&country=Brazil&style=Eletronic&price=23&artist=me Insere ou atualiza um álbum com id igual a 12 com o nome, país Brasil, estilo eletrônico, preço 23 e o artista eu

Tabela 2: Exemplos de serviços com o rest

Com isso foi demonstrado as novidades da nova versão do Easy-Cassandra, versão 1.0.9, que visa facilitar a vida do desenvolvedor. Foi demonstrado as mudanças para anotações típicas do jpa, novo recurso que recupera o timestamp da linha além do uso do JPQL por parte do framework. Muito ainda se tem de melhorar na ferramenta, mas com ajuda da comunidade isso será possível.

Link:

Exemplo servidor rest (AlbumServerRest.rar): https://github.com/otaviojava/Easy-Cassandra/downloads

Poster Plugin Firefox: https://addons.mozilla.org/en-US/firefox/addon/poster/

Easy-Cassandra: https://github.com/otaviojava/Easy-Cassandra/

Download o código e a documentação para a versão 1.0.9 ( documento 03): https://github.com/otaviojava/Easy-Cassandra/downloads

Artigos relacionados