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.

JPA Mini Book – First Steps and detailed concepts

Hello, how are you?

Today we will see about JPA: what is the persistence.xml file used for, how to create an entity, mapping easy and complex ids, creating relationships between the entities, automatically entity persistence and more.

Today we will see:

  • Page 02: Reasons that led to the creation of JPA
  • Page 03: What is JPA? What is a JPA Implementation?
  • Page 04: What is the persistence.xml file used for? And its configurations?
  • Page 05: Entity definitions. What are the Logic and Physical annotations?
  • Page 06: Id Generation: Definition, using Identity or Sequence
  • Page 07: Id Generation: TableGenerator and Auto
  • Page 08: Simple Composite Key
  • Page 09: Complex Composite Key
  • Page 10: How to get an EntityManager
  • Page 11: Mapping two or more tables in one entity
  • Page 12: Mapping Hierarchy: MappedSuperclass
  • Page 13: Mapping Hierarchy: Single Table
  • Page 14: Mapping Hierarchy: Joined
  • Page 15: Mapping Hierarchy: Table per Concrete Class
  • Page 16: Pros/Cons of each hierarchy mapping approach
  • Page 17: Embedded Objects
  • Page 18: ElementCollection – how to map a list of values into a class
  • Page 19: OneToOne unidirectional and bidirectional
  • Page 20: OneToMany/ManyToOne unidirectional and bidirectional
  • Page 21: ManyToMany unidirectional and bidirectional
  • Page 22: ManyToMany with extra fields
  • Page 23: How the Cascade functionality works? How should a developer use the OrphanRemoval? Handling the org.hibernate.TransientObjectException
  • Page 24: How to delete an entity with relationships. How to know which relationships are raising the exception
  • Page 25: Creating one EntityManagerFactory by application
  • Page 26: Understanding how the Lazy/Eager option works
  • Page 27: Handling the “cannot simultaneously fetch multiple bags” error

Just one more observation: I will not create a PDF file of this post. Just to create this material I already take several hours of code formatting, images production, translate all text to the English language and texts adjusts in this blog page. I am sorry, but there is no way to create a PDF file, maybe sometime later but I will not promise.

JSF Mini Livro – Dicas, conceitos e boas práticas

Olá, tudo bem?

Este post foi uma tentativa de escrever um artigo para uma revista de Java aqui do Brasil. Infelizmente não deu certo =(.Resolvi postar o artigo aqui! =D

Este artigo irá mostrar dicas, informações e soluções para os desenvolvedores que trabalham dia a dia com JSF 2.0. Serão apresentados conceitos e modos de usar o JSF para aqueles que trabalham com essa tecnologia ou tem interesse em conhecer mais sobre – estudantes, profissionais que trabalham com outros frameworks etc. Utilizar uma ferramenta sem entendê-la pode trazer problemas ao invés de soluções. É preciso entender o funcionamento do JSF, como ele trata cada ação do usuário e como é possível construir um código que otimize a utilização dessa ferramenta.

Serão apresentadas questões técnicas assim como: importar imagens/javascript para dentro das páginas, migrar um projeto JSF da versão 1.2 para a 2.0, utilizar o Ajax que é uma tecnologia de requisições assíncrona, entre outras; procurando abordar o lado teórico que freqüentemente é deixado de lado.

Com o JSF podemos enfrentar um dos maiores problemas da tecnologia web que é a dificuldade de reutilizar um código já escrito. O JSF nos permite reaproveitar páginas, códigos javascript, validações em código Java que são utilizados nas páginas. A reutilização dos códigos diminui o tempo gasto na manutenção das páginas da aplicação, reduz o impacto de mudanças, dentre outras vantagens.

O que será falado no post de hoje:

  • Página 02: Criando um projeto JSF
  • Página 03: Importando CSS/Imagens/JavaScript como biblioteca
  • Página 04: Reutilizando páginas com Facelets
  • Página 05: JSP x Facelets
  • Página 06: Escondendo os comentários da página xhtml
  • Página 07: Evite @SessionScoped. Veja todos os tipos de Escopos
  • Página 08: Evite colocar lógica nas páginas
  • Página 09: Utilize h:outputLink para navegação
  • Página 10: Ajax com JSF 2.0
  • Página 11: Facilitando o desenvolvimento com JSF 2.0
  • Página 12: Migrando do JSF 1.2 para o JSF 2.0
  • Página 13: Recebendo “null” da view
  • Página 14: Quando utilizar “action” ou “actionListener”
  • Página 15: Flash Scope
  • Página 16: Não misturar implementações do JSF
  • Página 17: Internacionalização como boa prática
  • Página 18: O que há de novo no JSF 2.2
Esse post também irá comemorar as mais de 200.000 visitas que o blog já recebeu nesses 2 anos de vida. [=

JSF Mini Book – Tips, concepts and good practices

Hello, how are you?

This post was written as an article to a Brazilian Java magazine. Unfortunately it was not published =(. I decided to post it here! =D

This post will display tips, concepts and solutions to developers that works with JSF 2.0 every day. We will see the concepts and the right way of using the JSF to help those who works with this technology or has interest in learning it – students or developers that works with others frameworks. Using this tool without knowledge of it will give more problems to your software instead solutions. It is really needed to understand how the JSF works, how it handles each user action request and how it is possible to build a software code that will optimize the JSF usage.

We will see some technical questions like: importing images/javascript into the pages, how to upgrade a JSF 1.2 app to a JSF 2.0, using Ajax that is a technology of asynchronously requests, and more; we will see some needed theory that is usually set aside.

With JSF we will be able to face one of the major problems of the web technology, code reuse. The JSF allow us to reuse the code of pages, javascript and validations in Java code that are used in the pages. When we reuse the code we will reduce the maintenance time expend, the change impacts will reduce also and others.

Today we will see:

  • Page 02: Creating a JSF project
  • Page 03: How to import CSS/Images/JavaScript as Library
  • Page 04: XHTML page reuse with Facelets
  • Page 05: JSP x Facelets
  • Page 06: Hiding the comments of the xhtml page
  • Page 07: Avoiding @SessionScoped type. Check all Scope Types
  • Page 08: Avoiding the use of logic in the xhtml page
  • Page 09: Use the h:outputLink to navigate
  • Page 10: Ajax with JSF 2.0
  • Page 11: Smoothing the JSF development
  • Page 12: Upgrading from JSF 1.2 to 2.0
  • Page 13: How to receive null value from the view
  • Page 14: Choosing between action and actionListener
  • Page 15: Flash Scope
  • Page 16: Dot no mix JSF Implementations
  • Page 17: Internationalization as good practice
  • Page 18: JSF 2.2 new features

This post is a celebration for the mark of 200k of viewers that we received in the two years of existence of this blog.

O “Pai do Java” usa Jelastic

Olá, tudo bem?

Hoje o post será diferente, será um informativo sobre essa ferramenta que tem crescido muito. O Jelastic tem por característica ser um servidor de servidores.

O material do post me foi enviado pelo Judah Johns da Jelastic.

Dr. James Gosling que é conhecido como um “Pai do Java” e tem uma longa carreira no ramo da tecnologia. Formado em no ano 1977 pela faculdade de Calgary, Canadá. Tornou PhD 1983 pela faculdade Carnegie-Mellon com a tese: “The Algebraic Manipulation of Constraints”. Durante muitos anos foi VP & Fellow da empresa Sun. Ele construiu sistemas para captação de informações de satélites, multiprocessadores para Unix, compiladores, sistemas de e-mails e e diversos editores de texto.

Enquanto funcionário da Sun foi líder no projeto NeWS. Ele desenvolveu o design original do Java e codificou o compilador e a máquina virtual. Ele tem contribuído para Real-Time Specification for Java e tem sido pesquisador nos laboratórios da Sun focado em ferramentas para desenvolvimento. Dr. James também trabalhou dentro da Sun em cargos de gerência de produtos para desenvolvedores e usuários. Continuou pouco tempo na Sun após a aquisição da Oracle, depois passou pelo Google e hoje é o líder de desenvolvimento na Liquid Robotics onde ele desenvolve sistemas para Wave Glider, um robô aquático em desenvolvimento.

“The Father of Java” uses Jelastic

Hello, how are you?

Today we will have an unusual post, it is more like a good news about this framework that is getting its space in the development world. Jelastic has as characteristic to work as a container of containers.

This news were sent to me by Judah Johns from Jelastic.

As far as we can tell, this is the first PaaS that Dr. Gosling has given his endorsement. We reached out to him to confirm it, and sure enough, it turns out that he is a very happy Jelastic user and is very excited about what he can do with it and what he will be doing with it in the near future.

Though I know that in our community, most everyone knows who James Gosling is, there a lot of younger guys learning Java that have never heard of him, like my 13 year-old brother, Daniel, who is quite an avid Java coder. So, who is James Gosling?

The Dr. James Gosling Bio

This bio comes from Gosling’s own blog: James Gosling received a BSc in Computer Science from the University of Calgary, Canada in 1977. He received a PhD in Computer Science from Carnegie-Mellon University in 1983. The title of his thesis was “The Algebraic Manipulation of Constraints”. He spent many years as a VP & Fellow at Sun Microsystems. He has built satellite data acquisition systems, a multiprocessor version of Unix, several compilers, mail systems and window managers. He has also built a WYSIWYG text editor, a constraint based drawing editor and a text editor called `Emacs’ for Unix systems.

At Sun his early activity was as lead engineer of the NeWS window system. He did the original design of the Java programming language and implemented its original compiler and virtual machine. He has been a contributor to the Real-Time Specification for Java, and a researcher at Sun labs where his primary interest was software development tools. He then was the Chief Technology Officer of Sun’s Developer Products Group and the CTO of Sun’s Client Software Group. He briefly worked for Oracle after the acquisition of Sun. After a year off, he spent some time at Google and is now the chief software architect at Liquid Robotics where he spends his time writing software for the Wave Glider, an autonomous ocean-going robot.

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_

EasyCriteria 1.0 released

Hello, how are you?

This post will talk about the new functionalities of EasyCriteria.

EasyCriteria is a tool (Open Source) to make easier the JPA Criteria code for any kind of JPA implementation. EasyCriteria has 100% of coverage on its tests with JUnit and it is tested with: Hibernate, OpenJPA and EclipseLink.

If you want to understand the Criteria ideal and how to apply it to your code check this post: EasyCriteria – An easy way to use the JPA Criteria

The new EasyCriteria functionalities are:

  • Join with conditions
  • Query Pagination

Now it is possible to do a Join and add parameters to it:

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

The query can be paginated:

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

This new version also has 100% of code coverage.

Click here to download the code of this post with EasyCriteria. With this code you can test EasyCriteria as you like.

In the project page (http://easycriteria.uaihebert.com/) you will find all documentation.

If you have any doubt, just post it.

See you soon! o_

EasyCriteria – Utilizando a Criteria do JPA de um modo simples

Olá, tudo bem?

Vamos ver hoje sobre essa ferramenta que facilita o uso da Criteria do JPA que deixa o código bem limpo, fácil de utilizar e portável pelas implementações do JPA.

Ao final desse post se encontra disponível o código fonte para download.

O que é uma Criteria? É atualmente a melhor solução para consultas que são criadas de modo dinâmicos. Imagine uma tela onde se tem diversas opções de pesquisa. Pode ser por nome, por idade ou até mesmo pelos dois. Veja como ficaria a consulta caso fosse utilizado uma concatenação de String:

EntityManager em = emf.createEntityManager();
String hql = "select p from Person p where 1=1 ";

if(parameters[0].equals("name")){
	hql += " and p.name = '" + values[0] + "'";
}

if(parameters[1].equals("age")){
	hql += " and p.age = " + values[1];
}

TypedQuery<Person> query = em.createQuery(hql, Person.class);

System.out.println(query.getResultList());

Repare que no código acima é necessário fazer a concatenação de String o que pode levar ao famoso ataque hacker “SQL Injection”. A solução para evitar esse tipo de ataque seria utilizando query com parâmetros e não concatenação:

EntityManager em = emf.createEntityManager();
String hql = "select p from Person p where 1=1 ";

if(parameters.contains("name")){
	hql += " and p.name = :name";
}

if(parameters.contains("age")){
	hql += " and p.age = :age";
}

TypedQuery<Person> query = em.createQuery(hql, Person.class);

if(parameters.contains("name")){
	query.setParameter("name", values[0].toString());
}

if(parameters.contains("age")){
	query.setParameter("age", Integer.valueOf(values[1].toString()));
}

System.out.println(query.getResultList());

Note que o problema do SQL Injection foi resolvido mas agora o código deve verificar os parâmetros na hora de construir a query q na hora de popular os valores; o ato de popular os parâmetros acabam por gerar uma tarefa extra.

O pessoal da Java teve a brilhante ideia de criar o conceito de Criteria que é perfeita para esse tipo de utilização. Veja abaixo como ficaria o mesmo código utilizando a Criteria nativa do JPA:

EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);
cq.select(root);

if(parameters.contains("name")){
	Path<String> name = root.get("name");
	cq.where(cb.and(cb.equal(name, values[0])));
}

if(parameters.contains("age")){
	Path<Integer> name = root.get("age");
	cq.where(cb.and(cb.equal(name, Integer.valueOf(values[1].toString()))));
}

TypedQuery<Person> query = em.createQuery(cq);

System.out.println(query.getResultList());

Veja como ficou prático a passagem de parâmetros já com seu valor. Não existe a necessidade de concatenar string, ou muito menos de ficar populando parâmetros depois que a query estiver pronta.

Infelizmente essa api do Criteria ficou muito complexa e demasiadamente verbosa. Para fazer apenas um “select p from Person p” a criteria abaixo seria necessária:

EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);
cq.select(root);

TypedQuery<Person> query = em.createQuery(cq);
System.out.println(query.getResultList());

É muito código para uma função muito simples, listar todas as pessoas de uma tabela.

Para evitar toda essa verbosidade é que foi criado o projeto Open Source chamado EasyCriteria.

O EasyCriteria é simples, prático e tem uma abordagem de “esconder” toda a verbosidade facilitando o uso da Criteria do JPA. Utilizando o EasyCriteria a consulta acima ficaria assim:

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

if(parameters.contains("name")){
	easyCriteria.whereEquals("name", values[0]);
}

if(parameters.contains("age")){
	easyCriteria.whereEquals("age", values[1]);
}

System.out.println(easyCriteria.getResultList());

Note que toda a verbosidade do JPA foi embora. Agora é possível ter um código simples para a construção de um query dinâmica. Sobre o código acima vale a pena destacar:

  • Linha 2: Uma instância do EasyCriteria é criada através de uma “factory”. Essa factory existe para abstrair todos os passos necessários para a criação de um objeto do tipo EasyCriteriaImp. Nas versões futuras virão outros tipos de EasyCriteria virão a exemplo do Tuple.

  • Linhas 5 e 9: A passagem de parâmetros ficou mais objetiva. Agora para se passar um parâmetro para comparar valores (“name = :name”) basta utilizar o método equals que espera como primeiro parâmetro o nome do atributo da classe; e como segundo o parâmetro o valor a ser comparado.

  • Linha 12: Para realizar a consulta não é mais necessário a utilização da interface Query. O próprio EasyCriteria toma conta dessa função. É possível extrair diretamente o resultado da query pelo EasyCriteria. Existem dois métodos que fazem isso atualmente o “EasyCriteria.getSingleResult()” e o “EasyCriteria.getResultList()”.

No site do EasyCriteria é possível encontrar diversos exemplos e os métodos que podem ser utilizados. Outra vantagem de se utilizar o EasyCriteria é que todos os seus comandos podem ser “linkados”:

easyCriteria.whereEquals("name", values[0]).whereEquals("age", values[1]).getResultList();

É uma bilioteca que está leve pois a única dependência é o JPA que o sistema já terá que ter configurado. Atenção: é necessário que sua aplicação já tenha o JPA rodando com alguma implementação.

Essa biblioteca foi desenvolvido utilizando JUnit e testado com Hibernate, OpenJPA e EclipseLink. O JUnit também utiliza do framework Cobertura para verificar se todo o código está sendo testado, atualmente 100% do código está coberto.

O EasyCriteria se encontra na versão beta e já tem em vista novas releases com novas funcionalidades.

Outra vantagem do EasyCriteria é que seu código não fica acoplado à alguma implementação. Hoje o Hibernate tem uma ferramenta de criteria muito boa e prática, mas você tem que ficar “preso” a ele. Com o EasyCriteria você poderá utilizar qualquer implementação. A prova disso é que os testes do EasyCriteria são realizados com as implementações citadas agora a pouco.

E EasyCriteria facilita funções como in, like, empty para a criteria do JPA. Além de realizar join (simples, sem adição de parâmetros), distinct e até order by tudo por criteria.

Aqui você encontra o EasyCriteria para download e para acesso a toda sua documentação (http://easycriteria.uaihebert.com).

Clique aqui para fazer o download do código fonte do post de hoje.

Espero que esse post/ferramenta possa te ajudar.

Qualquer dúvida/questionamento/opnião basta falar.

Até a próxima! o_

EasyCriteria – An easy way to use the JPA Criteria

Hello, how are you?

Today we will see about this tool that make easier to use the JPA Criteria. The application that uses this library will be cleaner, easier to use and portable across the JPA implementations.

At the end of this post you will find the source code to download.

What is Criteria? Currently is the best solution to create dynamic queries. Imagine a page that allows the user to do several types of queries; the requested query could be by name, by age or with both. Take a look bellow in how the query would look like if we concatenate a String:

EntityManager em = emf.createEntityManager();
String hql = "select p from Person p where 1=1 ";

if(parameters[0].equals("name")){
	hql += " and p.name = '" + values[0] + "'";
}

if(parameters[1].equals("age")){
	hql += " and p.age = " + values[1];
}

TypedQuery<Person> query = em.createQuery(hql, Person.class);

System.out.println(query.getResultList());

Notice that in the code above a String concatenation is made; remember that this practice is a bad and dangerous practice because it allows “SQL Injection” hacker attack. To avoid this attack we should use a query with parameters:

EntityManager em = emf.createEntityManager();
String hql = "select p from Person p where 1=1 ";

if(parameters.contains("name")){
	hql += " and p.name = :name";
}

if(parameters.contains("age")){
	hql += " and p.age = :age";
}

TypedQuery<Person> query = em.createQuery(hql, Person.class);

if(parameters.contains("name")){
	query.setParameter("name", values[0].toString());
}

if(parameters.contains("age")){
	query.setParameter("age", Integer.valueOf(values[1].toString()));
}

System.out.println(query.getResultList());

Notice that the SQL Injection problem were solved but now the code must check parameters to add it to the query and later to pass its values; the code needs of two “parameters searches” to complete the task.

The Java/Oracle developers had the brilliant idea when they created the Criteria concept that is perfect to this kind of situation. Check bellow how the code would look like with the native JPA Criteria:

EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);
cq.select(root);

if(parameters.contains("name")){
	Path<String> name = root.get("name");
	cq.where(cb.and(cb.equal(name, values[0])));
}

if(parameters.contains("age")){
	Path<Integer> name = root.get("age");
	cq.where(cb.and(cb.equal(name, Integer.valueOf(values[1].toString()))));
}

TypedQuery<Person> query = em.createQuery(cq);

System.out.println(query.getResultList());

Is possible to see that to pass the parameters values is easier. There is no need to concatenate the String or to check the parameters list values to populate the values.

Unfortunately the Criteria API is to complex and verbose to the extreme. If you want to do only a “select p from Person p” you would need to create the criteria bellow:

EntityManager em = emf.createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);
cq.select(root);

TypedQuery<Person> query = em.createQuery(cq);
System.out.println(query.getResultList());

Is to much code to do something so easy, list all persons from a table.

To avoid all this verbosity the Open Source project named EasyCriteria were created. If a developer uses the EasyCriteria the query above would look like bellow:

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

if(parameters.contains("name")){
	easyCriteria.whereEquals("name", values[0]);
}

if(parameters.contains("age")){
	easyCriteria.whereEquals("age", values[1]);
}

System.out.println(easyCriteria.getResultList());

Notice that the all JPA verbosity is gone. Now it is possible to have a clean code, easier to create dynamic queries. About the code above is worth to talk about:

  • Line 2: An instance of the EasyCriteria is created through a “factory”. This factory exists to do the abstraction of the every needed steep to create an object of the EasyCriteriaImp type. In the future verions new types of the EasyCriteria will be added, e.g. “Tuple”.
  • Lines 5 and 9: It is easier to pass the parameters. To pass the parameters to compare values (“name = :name”) just use the equals method that take as first parameter the attribute name; the second parameter will be the value that will be equaled.
  • Line 12: To run the query it will not be necessary to use the Query interface. The EasyCriteria itself takes this responsibility. It is possible to extract the query result through the EasyCriteria. There are two methods available to get the query result: EasyCriteria.getSingleResult(), EasyCriteria.getResultList().

In the EasyCriteria web page it is available several code samples and the methods that can be used. Other advantage of the EasyCriteria is the ability to “link” all methods:

easyCriteria.whereEquals("name", values[0]).whereEquals("age", values[1]).getResultList();

It is an light weight library because the only dependency is the JPA that the system will need to have. Attention: your application will need to have a JPA implementation up and running.

This library was developed with JUnit and tested with Hibernate, OpenJPA and EclipseLink. The JUnit also uses the Cobertura framework to check if all code lines (or most of it) are covered by the tests, so far we got 100% of coverage.

EasyCriteria still in Beta but the development team already got planed some releases and functionalities.

Other EasyCriteria advantage is that your software code in no long “coupled” to any kind of JPA implementation. Today the Hibernate has a good criteria tool, but your code must stay “attached” to it. With the EasyCriteria you will be able to use any kind of JPA implementation. The proof of this decoupled library is that the EasyCriteria has been tested with 3 implementations quoted earlier.

The EasyCriteria has the methods: in, like, empty and others. The developer will be able to do join (just simple joins without parameter), distinct or even order by all with Criteria.

Here you will find the EasyCriteria to download and have access to all its documentation.

Click here to download the source code of this post.

I hope that this post/tool may help you.

If you have any doubt/question/comment just post it.

See you soon! o_