uaiMockServer – Crie um servidor Rest de teste com apenas uma linha de comando

Olá, tudo bem?

Sabe aquele momento em que você precisa chamar um serviço REST, mas esse serviço não está pronto ainda?

Imagine que você está desenvolvendo uma nova tela do APP que o serviço REST ainda não está pronto. Nesse caso você precisará ter um código falso em seu projeto, e esse código terá que ser substituído quando o serviço ficar pronto. Não importa se você trabalha com Java, .NET, PHP, Ruby, Python, etc.. Você terá que ter sempre o trabalho de primeiro criar o mock e depois criar a chamada real quando o serviço REST não estiver pronto.

Para testes unitários temos o mesmo problema, é comum termos uma classe com a implementação real e uma classe com um código falso. Na hora do teste é que a classe falsa é utilizada. O ruim dessa abordagem é que o código que executa a chamada nunca é testado.

Como podemos resolver esse problema? E o mais interessante: “existe uma solução que atenda delphi, .NET, PHP, Java, Android, IOS, WindowsPhone, etc?”

Apresento para vocês o mais novo produto que criei: “uaiMockServer

Com o uaiMockServer você poderá criar um servidor de teste utilizando o JAR e um arquivo de configuração. Com o uaiMockServer você poderá disparar os testes usando HTTP, mas com seus dados de testes.

Existem dois modos de utilizar o uaiMockServer: Standalone e com Testes Unitários.

Standalone

O modo standalone é quando você dispara o jar manualmente. Para executar o serviço manualmente basta fazer:

java -jar uaiMockServer-{VERSION}.Standalone.jar

Tudo o que você precisa agora é do arquivo de configuração que estará descrito mais abaixo.

No arquivo exemplo de configuração já vem mapeado um hello world apontando para a porta 1234. Se você estiver usando linux, execute o comando:

curl localhost:1234/uaiMockServer/

E você já verá o JSON retornado.

Testes Unitários

Primeiro passo é adicionar o projeto em seu pom:

<dependency>
   <groupId>uaihebert.com</groupId>
   <artifactId>uaiMockServer</artifactId>
   <version>1.0.1</version>
   <scope>test</scope>
</dependency>

Uma vez que a dependência já está em seu pom você pode criar um teste como o abaixo:

public class YourTest {
    private static UaiMockServer uaiMockServer;

    @BeforeClass
    public static void beforeClass() {
        uaiMockServer = UaiMockServer.start();
    }

    @AfterClass
    public static void afterClass() {
        uaiMockServer.shutdown();
    }

    @Test
    public void aTest() {
        final Customer customer = // invoke the URL
        assertTrue(customer != null);
    }
}

A chamada na URL tem que ser feita com algum framework de sua preferência. Eu coloco abaixo um exemplo feito utilizando RestEasy e o arquivo de configuração (mostrado mais abaixo):

@Test
public void isGetRootReturning200() {
    final String url = "http://localhost:1234/uaiMockServer/";

    Client client = ClientBuilder.newClient();
    Response response = client.target(url).request().get();

    assertEquals(200, response.getStatus());
}

A vantagem disso? Agora você não precisa mais de um código mock em seus testes. Você pode chamar diretamente do JUnit o servidor criado.

Configuração

Para rodar corretamente é necessário um arquivo de configuração. Um exemplo simples seria o arquivo abaixo:

com.uaihebert.uaimockserver {
	port = 1234
	host = localhost
	fileLog = false
	consoleLog = true
	context = /uaiMockServer
	defaultContentTypeResponse = "text/html;charset=UTF-8"
	routes = [
	    {
			request {
				path = "/"
				method = "GET"
			}
			response {
				contentType = "application/json;charset=UTF-8"
				statusCode = 200
				body = """{"mockBody":{"title":"Hello World"}}"""
			}
	    }
    ]
}

O arquivo tem que ter a extensão .config e não está no formato JSON, mas sim é um superset do JSON – HCON – utilizado para configurações (clique aqui para mais detalhes).

Com esse arquivo você pode configurar a porta a ser chamada, o host, header, queryparam e diversas outras funções que estão descritas na documentação do uaiMockServer.

Note que foi criado um request e response desse modo você pode simular toda chamada que você quiser.

Caso você rode a versão Standalone, esse arquivo deve ficar na mesma pasta que o jar. Você também pode passar o caminho completo assim:

java -jar uaiMockServer-{VERSION}.Standalone.jar CAMINHO_COMPLETO_DO_ARQUIVO

Caso você vá rodar o serviço em seus testes unitários (JUnit por exemplo), você deve colocar o arquivo na pasta “src/test/resources” do maven. Você também poderia passar o caminho completo do arquivo como:

uaiMockServer = UaiMockServer.start(CAMINHO_COMPLETO_DO_ARQUIVO);

É grátis?

Sim. Use a vontade.

O código fonte é aberto? Sim: https://github.com/uaihebert/uaiMockServer

A documentação está onde? http://uaimockserver.com

E para baixar o .config e o JAR Standalone? http://sourceforge.net/projects/uaimockserver/files/

Tem teste? Sim, Temos bastantes testes unitários e 100% de cobertura.

Performance desse trem é bom?

No próprio GIT tem um teste que dispara 300 requests e tem todas as resposta em menos de 2 segundos.

Agradecimentos Especiais

EasyCriteria evoluiu para uaiCriteria. Novo nome e novas funcionalidades

Olá, tudo bem?

É com muita felicidade que venho anunciar o uaiCriteria, a evolução do EasyCriteria.

Por que a mudança de nome? Descobri que já existia no mercado um framework com o mesmo nome e para evitar qualquer problema eu resolvi mudar o nome do framework. A diferença é que o uaiCriteria trabalha com String como parâmetro, e o outro framework trabalha com MetaModel diretamente.

Para esclarecer algumas dúvidas sobre a mudança:

  • Seu código antigo continuará funcionando sem problema algum, o código é retro compatível

  • As classes EasyCriteira estão marcadas com @Deprecated e serão removidas na próxima versão

  • As novas classes tem os mesmo métodos que as antigas e muitas outras novidades. Basta fazer um “replace” de EasyCriteria por UaiCriteria e todo problema estará resolvido

  • Novamente, eu não queria mudar o nome mas também não quero problemas com outras pessoas

O framework também ganhou um mascote, eu espero que vocês gostem:

mascote

mascote

De novidades temos muitas, mas muitas mesmo! Vamos ver primeiro mudanças de estrutura:

  1. O site mudou, agora o site é o: http://uaicriteria.com

  2. O repositório mudou, agora estamos hospedados no GIT. Após diversos pedidos movi para o GIT para melhorar a visualização do código: https://github.com/uaihebert/uaicriteria

  3. Para ajudar na cobertura do código e análise estática foi adicionado o plugin do SONAR. A imagem de cobertura agora ficou até mais bonita:

    uaicriteria cobertura

    uaicriteria cobertura

  4. O site antigo será desativado e todos os dados antigos foram levados para site novo, até mesmo a documentação legada. [=

  5. A API atual existe limitações, algo como não possibilitar o uso do HAVING e algumas outras funções, desse modo será criada para próxima versão uma Interface/API para Criterias Complexas – aceito sugestão de nome para a Interface (:

Com relação ao código, temos diversas novidades:

Boas vindas ao Batoo

O Batoo é um provedor de JPA assim como EclipseLink ou Hibernate. Com essa nova versão diversas funcionalidades foram cobertas com o Batoo.

Note que eu disse diversas, mas não todas. Infelizmente o Batoo ainda tem muitos, mas muitos problemas mesmo com consultas e Criterias.

O uaiCriteria ainda dá cobertura aos frameworks Hibernate, EclipseLink e OpenJPA na maioria dos métodos.

MultiSelect

É possível escolher quais campos serão retornados em uma consulta, veja a JPQL:

select 
    p.name, 
    p.age

from Person p

Transformando a consulta acima em criteria:

final UaiCriteria<Person> uaicriteria = 
    UaiCriteriaFactory.UaiCriteriaFactory.createMultiSelectCriteria(entityManager, Person.class);

uaiCriteria.addMultiSelectAttribute("name")
           .addMultiSelectAttribute("age");

final List multiselectList = uaiCriteria.getMultiSelectResult();

Algumas considerações sobre o código acima:

  • O resultado terá um Object caso você retorne apenas um campo

  • O resultado terá um Object[] caso você retorne diversos campos

  • A implementação pode variar de Object[] ou Vector (pelo menos comigo o EclipseLink estava retornando Vector)

SubQuery

Agora é possível fazer subQuery. Imagine uma JPQL como a abaixo:

select p from Person p 
where p.id in 
        (select dog.person.id from Dog dog where dog.cute = true)

Nem vou citar quantas linhas de código seriam necessárias para fazer o código acima, mas com o UaiCriteria ficou bem mais fácil:

final UaiCriteria<Person> uaiCriteria = UaiCriteriaFactory.createQueryCriteria(Person.class);

final UaiCriteria<Dog> subQuery = uaiCriteria.subQuery("person.id", Dog.class); // dog.person.id

subQuery.andEquals("cute", true);

uaiCriteria.andAttributeIn("id", subQuery); //person.id

Basta criar um objeto de subQuery passando qual será o retorno da subQuery. Depois chame o método o attributeIn(…) da query principal passando qual o campo a ser comparado.

MapIsEmpty [NOT]

Agora é possível utilizar a função isEmpty com Map:

uaiCriteria.andCollectionIsEmpty("ENTITY_MAP");

AttributeIn [NOT]

Existe a opção de verificar se um valor está ou não dentro de uma lista. Veja o exemplo abaixo:

select p
from Payment p
where
    p.statusEnum in :enumList

Para transformar o código acima em criteria:

final UaiCriteria<Payment> uaiCriteria = 
    UaiCriteriaFactory.createQueryCriteria(Payment.class);

uaiCriteria.andAttributeIn("statusEnum", 
                           Arrays.asList(StatusEnum.VALUE_01, StatusEnum.VALUE_02));

O atributo não precisa ser necessariamente um enum, poder ser número, string, etc.

MemberOf [NOT]

A consulta abaixo

select d
from Departament d
where :person member of d.employeeList

Pode ser criada como:

final UaiCriteria<Departament> uaiCriteria = UaiCriteriaFactory.createQueryCriteria(Departament.class);

uaiCriteria.andIsMemberOf(person, "employeeList");

Count e CountRegularCriteria

Agora como é possível realizar uma consulta MultiSelect o método count() foi renomeado como countRegularCriteria(). Funciona do mesmo modo, houve apenas uma alteração no nome para ficar mais claro seu funcionamento.

CountAttribute

Existe situações onde é necessário realizar o count em cima de um atributo, algo como:

select count(p.id)
from Person p

E para executar como Criteria:

final UaiCriteria<Person> uaiCriteria = 
    UaiCriteriaFactory.createMultiSelectCriteria(Person.class);

uaiCriteria.countAttribute("id");

final List result = uaiCriteria.getMultiSelectResult();

GroupBy e funções de Agregação

Agora é possível realizar groupBy juntamente com diversas funções de agregação. Funções como sum, diff, divide, module, etc.

select sum(p.value), p.status
from Payment p
group by p.status

Poderia se executada como:

final UaiCriteria<Payment> uaiCriteria = 
    UaiCriteriaFactory.createMultiSelectCriteria(Payment.class);

uaiCriteria.sum("id").groupBy("status");

final List result = uaiCriteria.getMultiSelectResult();

Novo Import no Maven

Para utilizar a nova versão em seu projeto, basta adicionar o código abaixo ao seu pom.xml

<dependency>
    <groupId>uaihebert.com</groupId>
    <artifactId>uaiCriteria</artifactId>
    <version>4.0.0</version>
</dependency>

Bem, espero que você tenha gostado das novidades.

Não esqueça de visitar o site —————-> http://uaicriteria.com

Qualquer dúvida/crítica/sugestão basta falar.

Até mais. o_

Alternativas ao JPA Hibernate. O que usar quando o JPA não atende meu projeto?

Olá, tudo bem?

Hoje vamos falar sobre situações onde o JPA pode não nos atender. Com quais alternativas podemos contar a partir do momento que percebemos que o JPA não está ajudando?

O que vamos ver aqui hoje:

  • Problemas do JPA e do Hibernate
  • Soluções para problemas do JPA
  • Critérios para escolha dos frameworks descritos aqui
  • Spring JDBC Template
  • MyBatis
  • Sormula
  • sql2o
  • Vale a pena conferir: jOOQ e Avaje
  • E o JDBC puro? Ainda vale a pena?
  • Considerações sobre qual framework escolher
  • Conclusão

Criei em meu github 4 CRUDS completos das ferramentas detalhadas aqui no post, cada URL está em cada página que descreve o framework.

Eu não sou o tipo de pessoa radical que acha que o JPA não serve para nada, pelo contrário, creio que em determinados momentos é necessário escolher o framework mais adequado para a cada situação. Para quem não sabe eu já escrevi um livro de JPA e ainda assim não o considero a bala de prata para todos os problemas.

Espero que vocês gostem. [=

Novo livro lançado: JPA Eficaz: As melhores práticas de persistência de dados em Java

Pessoal, bom dia.

É com muita alegria que gostaria de compartilhar que meu novo livro acabou de ser lançado.

JPA Eficaz: As melhores práticas de persistência de dados em Java

JPA-Eficaz-ebook_large

Ele aborda diversos assuntos do JPA, desde os conceitos básicos como analisando o persistence.xml a como fazer controle de concorrência.

Aqui é possível fazer o download de todo o sumário do livro: https://s3.amazonaws.com/casadocodigo/jpa-eficaz/sumario.pdf

São 173 páginas com códigos detalhados, explicações do conceito do JPA com exemplos que se aplicam ao nosso dia a dia.

Uma lista de discussão do livro já foi criada e é livre para qualquer participar: https://groups.google.com/d/forum/jpa-eficaz

Para comprar o livro, basta vir aqui: http://www.casadocodigo.com.br/products/livro-jpa-eficaz

E aguardem que até o final do ano, mais um mini livro de um assunto ainda não detalhado aqui no blog. ;)

EasyCriteria 3.0 – Novas funcionalidades

Olá, tudo bem?

É com muita felicidade que anuncio mais uma versão do EasyCriteria. E essa versão agora é para facilitar e ampliar e muito a utilização do framework (caso você não conheça e queira conhecer mais sobre o EasyCriteria clique aqui).

São 2 features e um enorme refactor nessa nova versão que o EasyCriteria até mereceu mudar a versão principal do framework de 2 para 3.

Vamos lá:

Extreme Refactoring

Houve uma refatoração no código onde foi reduzida a complexidade do código, aplicado padrões, atributos como “final” para melhorar alocação de memória e dependências do pom.

Versão 3.0
cobertura_30

Versão 2.2
cobertura_22

Note houve uma diminuição na complexidade ciclomática dos pacotes (mais sobre o teste de complexidade aqui). Apenas o pacote de utils que houve um singelo aumento da complexidade mas ainda assim com redução do número de linhas.

Joins Inifinitos! o/

Pode parecer coisa simples e básica, mas essa era, até essa versão, o maior desafio. Agora é possível fazer quantos joins forem necessários. Veja o código abaixo:

EasyCriteria<Person> easyCriteria = EasyCriteriaFactory.createQueryCriteria(getEntityManager(), Person.class);

easyCriteria.innerJoin("dogs.toys.manufacturer");

easyCriteria.andEquals("dogs.toys.manufacturer.name", "ACME");

easyCriteria.orderByDesc("dogs.toys.name");

Analisando a consulta acima é possível perceber que agora é possível fazer todos os joins desejados para as diversas funcionalidades já existentes. Veja que o método “andEquals” está atravessando os relacionamentos existentes na Entity Person.

É possível ver também que até a ordenação agora aceita os diversos tipos de join.

O que simplificará também a API do EasyCriteria, pois agora não será necessário chamar nenhum outro método que tenha Join em seu nome para criar um “where”. O método andJoinEquals (ou qualquer outro que tenha Join no nome fazendo condição, ex.: andJoinGreaterThan, andJoinStringIn, …) está deprecated e marcado para remoção em futuras versões.

Count

Esse método permite fazer um count no resultado da query. Veja o código abaixo:

EasyCriteria<Person> easyCriteria = EasyCriteriaFactory.createQueryCriteria(getEntityManager(), Person.class);
System.out.println(easyCriteria.count());

O código acima exibiria o total de Pessoas cadastradas no banco de dados. Mas, seria possível fazer algo mais avançado?

A query abaixo funcionaria sem problemas:

List<String> names = new ArrayList<String>();
names.add("John");
names.add("Mary");

EasyCriteria<Manufacturer> easyCriteria = EasyCriteriaFactory.createQueryCriteria(getEntityManager(), Manufacturer.class);
easyCriteria.setDistinctTrue();
easyCriteria.innerJoin("products.sellers");
easyCriteria.andStringNotIn("products.sellers.name", names);
easyCriteria.setFirstResult(0);
easyCriteria.setMaxResults(50);

System.out.println(easyCriteria.count());
List<Manufacturer> manufactures = easyCriteria.getResultList();

Note no código acima que com o EasyCriteria é possível realizar um “count” e com o mesmo objeto realizar a consulta necessária.

É importante ressaltar que: o método count ignorará os valores definidos em setMaxResults e setFirstResult. Atualmente para utilizar esse tipo de count com maxResults e firstReslt seria necessário realizar uma subquery e atualmente isso não é feito pelo framework.

100% de cobertura

E o projeto ainda continua com 100% de cobertura em testes unitários com OpenJPA, Hibernate e EclipseLink utilizando JUnit e o plugin Cobertura.

Espere que a ferramenta seja bastante útil a todos vocês.

Para utilizar basta adicionar a dependência no POM:

<dependency>
    <groupId>uaihebert.com</groupId>
    <artifactId>EasyCriteria</artifactId>
    <version>3.0.0</version>
</dependency>

Ou fazer o download do jar aqui: http://uaihebert.com/wp-content/uploads/EasyCriteria/EasyCriteria-3.0.0_2013-08-02.jar

Até mais pessoal. o_

EasyCriteria – Novas funcionalidades

Olá pessoal, tudo bem?

Venho aqui falar da nova versão do EasyCriteria.

Para quem não conhece o EasyCriteria, ele facilita a utilização da Criteria Nativa do JPA.

A JPQL:

select p from Person p

Seria transformada no seguinte código em Criteria do JPA:

CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<Person> root = criteriaQuery.from(Person.class);
criteriaQuery.select(root);
TypedQuery<Person> query = entityManager.createQuery(criteriaQuery);
query.getResultList();

Veja quanta linhas para uma simples rotina. Como resolver esse problema?

Basta utilizar o framework chamado EasyCriteria:

EasyCriteria<Person> easyCriteria = EasyCriteriaFactory.createQueryCriteria(entityManager, Person.class);
easyCriteria.getResultList();

Veja como ficou fácil utilizar Criteria com JPA. As vantagens do EasyCriteria são diversas:

  1. Permite portabilidade: Você pode trocar entre as seguintes implementações Hibernate, EclipseLink e OpenJPA sem problemas.
  2. 100% de cobertura nos testes. test coverage
  3. Facilidade na utilização: EasyCriteria tem como princípio exportar o mínimo de API possível para o usuário. O desenvolvedor precisaria apenas utilizar a Interface EasyCriteria para realizar todas as operações.
  4. Boa ferramenta para iniciantes em JPA, pois a API tem seus métodos bem explicados e fáceis de utilizar.
  5. Está no repositório do Maven.

E o que existe de novidades na nova versão?

A primeira novidade é o conceito de Criteria Transfer Object (CTO). Agora é possível criar um objeto na view, sem a necessidade do EntityManager, para carregar todas as informações relacionadas a pesquisa e aplicar na consulta.

Veja como funcionaria o conceito de CTO abaixo:

public void controllerMethod(Integer id){
   EasyCriteria easyCTO = EasyCriteriaFactory.createEasyCTO();
   easyCTO.andEquals("id", id);

   myDAO.deactivateCar(easyCTO);
}
// and in the method
public void deactivateCar(EasyCriteria easyCTO){
    EasyCriteria<Car> easyCriteria = EasyCriteriaFactory.createQueryCriteria(entityManager, Car.class, easyCTO);
    Car car = easyCriteria.getSingleResult();
    car.deactivateCar();
}

Agora é bem simples e fácil montar sua query onde já existem os parâmetro e depois enviá-las para a camada de negócio/repositório. [=

E a outra novidade é permitir a comparação por LowerCase:

boolean toLowerCase = true;

EasyCriteria<Person> easyCriteria = EasyCriteriaFactory.createQueryCriteria(getEntityManager(), Person.class);
easyCriteria.andEquals(toLowerCase, "name", "MARY");

Essa estava sendo também uma das funcionalidades mais pedidas pelos usuários do framework. Se você quiser uma funcionalidade também, basta pedir. [=

Para fazer o download manual, é possível baixá-lo aqui: https://code.google.com/p/easy-criteria/downloads/detail?name=EasyCriteria-2.2.2_2013-07-16.jar&can=1&q=#makechanges

Para baixar pelo Maven, basta adicionar a dependência abaixo:

<dependency>
	<groupId>uaihebert.com</groupId>
	<artifactId>EasyCriteria</artifactId>
	<version>2.2.2</version>
</dependency>

Espero que as novas funcionalidades possam agradar a vocês.

Até a próxima! o_

EasyCriteria no Maven

Pessoal, bom dia.

É com muito prazer que venho anunciar que o EasyCriteria foi adicionado ao repositório do Maven.

Para utilizá-lo basta adicionar a seguinte configuração no pom do seu projeto:

<dependency>
	<groupId>uaihebert.com</groupId>
	<artifactId>EasyCriteria</artifactId>
	<version>2.1.0</version>
</dependency>

Simples e fácil. A versão 2.1.0 foi lançada para atender ao requisitos da publicação no Maven.

Espero que vocês gostem dessa novidade! [=

http://easycriteria.uaihebert.com

EasyCriteria 2.0 – JPA Criteria tem que ser simples

Olá, tudo bem?

Muito tempo se passou desde meu último post, mas não estava parado durante esse tempo.

O post de hoje vem falar sobre a nova versão do Framework chamado EasyCriteria. Ao final deste pequeno post eu conto mais o que estar por vir. [=

Infelizmente um grande problema da Criteria do JPA é sua verbosidade. Por que não facilitar? Foi pensando desse modo que nasceu o framework EasyCriteria e agora a recente versão 2.0.

Para fazer um simples select que busque todas as linhas do banco de dados, o seguinte código seria necessário:

CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<Person> root = criteriaQuery.from(Person.class);
criteriaQuery.select(root);
TypedQuery<Person> query = entityManager.createQuery(criteriaQuery);
query.getResultList();

Note quanto trabalho para apenas reproduzir a JPQL : select p from Person p.

Agora, veja como o EasyCriteria facilita a construção da mesma Criteria acima:

EasyCriteria<Person> easyCriteria = EasyCriteriaFactory.createQuery(entityManager, Person.class);
easyCriteria.getResultList();

A diferença da versão 1.0 e 2.0 está na redução de métodos e na criação de métodos genéricos que facilitem a utilização do projeto. Para comparar valores com os símbolos =, >, >=, <=, < e outro mais, basta fazer como abaixo:

easyCriteria.andGreaterThan("hairSize", 10.4f); // >

easyCriteria.andGreaterOrEqualTo("height", 11.00d); // >=

easyCriteria.andLessThan("totalBooksOwned", 30L); // <

easyCriteria.andLessOrEqualTo("firstJobDate", firstJobDate); // <=

easyCriteria.andJoinEquals("dogs", "age", 15); // =

easyCriteria.andJoinStringIn("dogs", "name", names); // value in (x, i, z, ...)

easyCriteria.andJoinStringLike("dogs", "name", "%y");

Uma ideia fixa do EasyCriteria é expor o menor número de API possível ao usuário. Visando essa ideia, a API incorporou o “OR” de uma query sem a necessidade expor outras classes.

Veja como fazer um “OR” simples:

select s from Song s where s.id = 1 or s.length = 40 or s.artist = 'Group 1 Crew'
easyCriteria.orEquals("id", 1).orEquals("length", 40).orEquals("artist", "Group 1 Crew");

E também poderia ser feito o seguinte tipo de query:

select s from Song s where (s.id = 1) or (s.id = 2) or (s.length = 40) or (s.artist = 'Group 1 Crew')
easyCriteria.orEquals("id", 1, 2).orEquals("length", 40).orEquals("artist", "Group 1 Crew");

E para casos mais complexos como a query abaixo, também é possível reproduzir com o EasyCriteria:

select s from Song s where (s.totalDownloads = 20 or s.weight = 10.00) and (s.price = 20.00 or s.type = :type)
easyCriteria.orEquals(1, "totalDownloads", 20L).orEquals(1, "weight", 10.00f).orEquals(2, "price", 20.00d).orEquals(2, "type", SongType.PRAISE);

Foi criada a ideia de índice para cada OR, ou seja, o primeiro grupo de OR é composto por totalDownloads e weight, já o seguinte grupo é price e type.

E como valor padrão o índice 1 é sempre utilizado. A criteria acima poderia ser traduzida por:

easyCriteria.orEquals("totalDownloads", 20L).orEquals("weight", 10.00f).orEquals(2, "price", 20.00d).orEquals(2, "type", SongType.PRAISE);

Para uma query que inverta esse quadro, onde AND é separado por OR basta fazer como abaixo:

select s from Song s where (s.id = 1 and s.name = 'Sing Out') or (s.id = 2 and s.name = 'Alive')
easyCriteria.addAndSeparatedByOr(1, "id", 1).addAndSeparatedByOr(1, "name", "Sing Out").addAndSeparatedByOr(2, "id", 2).addAndSeparatedByOr(2, "name", "Alive");

É isso pessoal, espero que vocês gostem da novidade. O framework está longe de se considerar pronto. E para bolar um modo de criar o OR foram queimados muitos neurônios com ajuda do João Neves (http://about.me/joaonevesfilho) e também o Sasaki (http://curriculum.rodrigosasaki.com/).

Aqui é possível ver a página oficial do framework: http://easycriteria.uaihebert.com. E o melhor, é free e open source (http://code.google.com/p/easy-criteria/).

Outra coisa legal é o fato de o projeto ter 100% de cobertura com plugin Cobertura e foi testado com OpenJPA, EclipseLink e Hibernate. É aí que eu peço a sua ajuda, pois foram encontrados bugs em todas implementações citadas. Seria possível você votar para que o bug seja resolvido?

EclipseLink: https://bugs.eclipse.org/bugs/show_bug.cgi?id=386354
OpenJPA: https://issues.apache.org/jira/browse/OPENJPA-2333
Hibernate: https://hibernate.onjira.com/browse/HHH-7985

E o que vem por aí? Em primeiro lugar eu demorei escrever um novo post, pois estou finalizando meu primeiro livro. Se Deus quiser até março ele será lançado.

E em segundo lugar estudei bastante Maven nesse tempo e pretendo lançar um próximo post de um mini livro só sobre ele contendo um básico e aplicações completas. Sim “aplicações” no plural mesmo.

Até a próxima pessoal! o_

JPA Mini Livro – Primeiros passos e conceitos detalhados

Olá, tudo bem?

Vamos ver hoje sobre JPA: o que é JPA, para que serve o persistence.xml, criar corretamente uma entidade, como realizar desde mapeamentos simples até os mapeamentos complexos de chaves primárias, criar relacionamentos entre as entidades, modos para persistência automática e outros.

O que iremos ver hoje:

  • Página 02: Quais os motivos que levaram à criação do JPA?
  • Página 03: O que é o JPA? O que são as implementações do JPA?
  • Página 04: Para que serve o persistence.xml? E suas configurações?
  • Página 05: Definições de uma “Entity”. O que são anotações Lógicas e Físicas?
  • Página 06: Gerando Id: Definição, Id por Identity ou Sequence
  • Página 07: Gerando Id: TableGenerator e Auto
  • Página 08: Utilizando Chave Composta Simples
  • Página 09: Utilizando Chave Composta Complexa
  • Página 10: Modos para obter um EntityManager
  • Página 11: Mapeando duas ou mais tabelas em uma entidade
  • Página 12: Mapeando Heranças – MappedSuperclass
  • Página 13: Mapeando Heranças – Single Table
  • Página 14: Mapeando Heranças – Joined
  • Página 15: Mapeando Heranças – Table Per Concrete Class
  • Página 16: Prós e Contras dos mapeamentos das heranças
  • Página 17: Embedded Objects
  • Página 18: ElementCollection – Como mapear uma lista de valores em uma classe
  • Página 19: OneToOne (Um para Um) Unidirecional e Bidirecional
  • Página 20: OneToMany (um para muitos) e ManyToOne (muitos para um) Unidirecional e Bidirecional
  • Página 21: ManyToMany (muitos para muitos) Unidirecional e Bidirecional
  • Página 22: ManyToMany com campos adicionais
  • Página 23: Como funciona o Cascade? Para que serve o OrphanRemoval? Como tratar a org.hibernate.TransientObjectException
  • Página 24: Como excluir corretamente uma entidade com relacionamento. Capturar entidades relacionadas no momento da exclusão de um registro no banco de dados.
  • Página 25: Criando um EntityManagerFactory por aplicação
  • Página 26: Entendendo o Lazy/Eager Load
  • Página 27: Tratando o erro: “cannot simultaneously fetch multiple bags”

Apenas uma observação: eu não irei criar o PDF desse post. Pra produzir o material já levo horas na formatação de código, produção de imagens, ajustes do post no blog e sem falar que preciso traduzir para o inglês. Desculpe, mas não existe a possibilidade, por agora, da criação de um arquivo PDF com o conteúdo deste post.

Dois leitores gente boa criaram arquivos para quem quiser fazer o download do post. Estão nos formatos pdf, doc e odt. É possível encontrar os arquivos na última página.

Lançado EasyCriteria 1.0

Olá, tudo bem?

Este post irá mostrar as novas funcionalidades do EasyCriteria.

O EasyCriteria é uma ferramenta Open Source que facilita a utilização do Criteria do JPA independente da implementação. Atualmente o EasyCriteira tem 100% de cobertura nos testes unitários e é testado com as implementações: Hibernate, OpenJPA e EclipseLink.

Caso você queira entender o conceito do Criteria e como pode ser aplicado ao seu projeto veja esse post: EasyCriteria – Um modo simples de fazer Criteria com JPA.

As novas funcionalidades do EasyCriteria 1.0 são:

  • Condições em Join
  • Paginação de Query

Agora é possível realizar um Join e adicionar parâmetros:

EntityManager em = emf.createEntityManager();
EasyCriteria<Person> easyCriteria = EasyCriteriaFactory.createQueryCriteria(em, Person.class);

easyCriteria.innerJoin("dogs", Dog.class);
easyCriteria.whereJoinEquals("dogs", "name", "Dark");
easyCriteria.whereJoinStringNotIn("dogs", "name", names); // names is a List<String>
easyCriteria.whereJoinStringLike("dogs", "name", "M%");
easyCriteria.whereJoinListIsEmpty("dogs", "cars");
easyCriteria.whereJoinAttributeIsNull("dogs", "nickName");
easyCriteria.whereJoinStringBetween("dogs", "name", "A", "L");

A query também poderá ser paginada:

EasyCriteria<Dog> easyCriteria = EasyCriteriaFactory.createQueryCriteria(getEntityManager(), Dog.class);
easyCriteria.setFirstResult(0);
easyCriteria.setMaxResults(5);

A nova versão também conta 100% de cobertura de código nos testes unitários.

Clique aqui para fazer o download do código do post de hoje do EasyCriteria. Você poderá testar os métodos do EasyCriteria.

Na página do projeto (http://easycriteria.uaihebert.com/) é possível encontrar toda a documentação.

Qualquer dúvida basta postar abaixo.

Até a próxima! o_