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 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
}
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 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 getProdutos() {
return persistenceService.findAllAlbum();
}
@Path("{id}")
@GET
@javax.ws.rs.Produces(MediaType.TEXT_XML)
public Album getAlbum(@PathParam("id") long id) {
return persistenceService.findById(id);
}
@Path("update/{id}")
@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("{id}")
@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