Tutorial Hibernate 3 with JPA 2

Hello, how are you?

Today we will study about an important framework to persist your model: “Hibernate”.
To do the Hibernate more powerful in this “HelloWorld” we will be integrating it with JPA.
When we mix this two APIs we do not have the need of mapping each model class in some xml file, but the EntityManager will handle it.

To start our work today we need to do some downloads.

Our first download will be the MySQL.
The download link is: http://dev.mysql.com/downloads/mysql/.

MySQL Site Image

To install the MySQL software you just have to apply the Microsoft installation pattern: “Next, Next, Finish”. Be aware about the password that you will type to your database. This password is needed to our XML configuration file.

Let us create a schema to the database by opening the “MySQL Command Line Client” that will be displaying in your Windows/Linux menu.

Hibernate JPA

Type the user/password that you typed in the MySQL installation. Type the command line below:

create database hello;

Push “Enter” and it is done.

Hibernate JPA

Our next download will be the Hibernate 3 library (click here if you want to find another versions to download).

Now we need to download the MySQL database connector (in here you can find other host to download).

The connector is the responsible to do the “talk” between the Hibernate and the database. We will use the MySQL database, but if you want to do with another database, you just have to do the download of the desired connector to your chosen database.

Hibernate API: Inside the file you have downloaded from the website you will find all the libraries that we need. Some of the libraries are: “Hibernate 3”, “JPA 2” and some others are required, soon you will see the libraries required list.
First create a java project of the type “Java Project”, then create a folder named “lib”to put in our downloaded libraries. To our application work correctly we will need the files listed bellow:

  • hibernate-distribution-3.6.0.Final/hibernate3.jar
  • hibernate-distribution-3.6.0.Final/lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar
  • hibernate-distribution-3.6.0.Final/lib/required/*” (All files are required)

Be aware of: The files that you will find inside the folder “required” are obligatory to the Hibernate 3. Copy all files listed above (and do not forget the files in the required folder) to the lib folder.

MySQL connector: As we did with Hibernate 3 library files we will do the same with the connector file. Inside the zip file, that you downloaded, there is a library named “mysql-connector-java-5.1.14-bin.jar”, copy this file into the lib folder.

In the end we will have our lib folder like the image bellow:

Hibernate JPA

We need to create a configuration file named “persistence.xml”. This file is mandatory for Hibernate configuration and it must be inside the folder “src/META-INF”. Take a look at the file dir and the folder structure (if you are reading this tutorial and you have searched other sources but your code still not working, your problem might be the xml headers. Some tutorials have an invalid “header” typed):

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    
    <persistence-unit name="Hello" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/Hello"/>
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

I will talk about each line of above code:

  • <persistence-unit name=”Hello” transaction-type=”RESOURCE_LOCAL”>” Two important configurations are present in this line: “unit name” defines to the application the name of the persistence configuration that we will use. In the same file, we are able to have more than one unit name. “transaction-type” sets our transaction type, in our case local. If we were doing a web application we would not need to control the transaction, the container (JBoss, Glassfish …) would do this job for us.
  • <provider>org.hibernate.ejb.HibernatePersistence</provider>” indicates which provider will “work” in our application. In our case we will use Hibernate.
  • “hibernate.show_sql” enables the SQL log to be shown in the console.
  • “javax.persistence.jdbc.driver” which “agent” will handle the database connection, we will use MySQL.
  • “javax.persistence.jdbc.url” our database url with the created schema.
  • “javax.persistence.jdbc.user” and “javax.persistence.jdbc.password” The database user and password. This attributes were defined when you installed the MySQL database. When I did the installation I typed the values “root”/“root”.
  • “hibernate.dialect” Dialect that the Hibernate will use. We will study more about this subject in a future post, by example, how to generate a database script.
  • “hibernate.hbm2ddl.auto” when this option has the true value, the Hibernate will update your tables when needed. If the table do not exist the Hibernate will create it (“CREATE TABLE…”), if you added a column (“ALTER TABLE…”). Just because this is a tutorial we will leave this option enabled, but it is not a good idea leave it activated in a real application. Again I say that it is not a good idea leave this option enabled for a real application. Turn it on only for local test or study.

One last step before we start to write our code. Add the libraries that we downloaded to the project build path. We need to do it so our application can use the libraries benefits.

Right mouse button click on the project: “Properties > Java Build Path”.

Click on Libraries tab and then “Add Jars”.

To finish this configuration, select all files that are inside the lib folder and click the button “Ok”.

Let us create the class “User” in the package “com”. With this model class we will do the CRUD (Create, Read, Update and Delete) operations.

package com;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="user")
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    
    @Column
    private String name;
    
    @Column
    private String password;
    
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof User){
            User user = (User) obj;
            return user.getId() == this.getId();
        }
        
        return false;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Some details about the above code:

  • “@Entity” will indicate to our Provider that this class should be persisted in our database.
  • “@Table” defines the table name that will be written in the database. If you do not define an attribute value to the field “name”, the default will be the same name of the class.
  • “@Id” defines the Id of the class.
  • “GeneratedValue” It is a key that defines that our Id will have a value created automatically using some pattern. In our sample code above we use the pattern AUTO.
  • “@Column” defines the attribute as a database table column. We could also define a name to the database table column by the attribute “name”, just like we did to the “@Table” annotation.

Now we need a class that will create the connection with the database and manager our model class User. Let us create a class named “Main” in the package “com”.

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = new User();
            user.setName("abc123");
            user.setPassword("abc123");
            
            em.persist(user);
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

Some details about the code above:

  • Notice that our application is a local application; we will need to control the connection manually. That is the reason of the method “beginTransaction”; we need also commit the changes and close the connection.
  • To persist our object User we use the method “em.persist(user);”

Just run the code and you will see a message indication success. To confirm just run a query into the database just like the images below:

Hibernate JPA

Hibernate JPA

Notice that, in the image above, the Hibernate created the insert sql script for us.

One of the greatest advantages of the Hibernate is that when you read an object from your database, it gives to you an object instead line strings. We use the method “find” to locate a database record by its Id:

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = em.find(User.class, 1);
            
            System.out.println(user.getName());
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

What do we must to do to update our user data? Let us change the user name, take a look how simple it is:

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = em.find(User.class, 1);
            
            user.setName("123abc");            
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

Hibernate JPA

To remove a record from the database, you just need to use the implemented method of the entity manager named “remove”. In our case you will invoke the method “find” again and then “em.remove (user);

I know this was a long post, but a hope it might help you.

In future posts we will be able to see about relationships and how to do the Ant + Hibernate generate database scripts.

If you have any doubt or any question, just post it.
See you later. o_

Tutorial Hibernate 3 com JPA 2

Olá pessoal, tudo bem?

Hoje vamos falar sobre um importante framework para tratar os dados do seu modelo: “Hibernate”.
Para fazer o Hibernate mais poderoso nesse “HelloWord” faremos com que ele trabalhe em conjunto com a API do JPA.
Trabalhando junto com o JPA não precisaremos mapear cada classe que for criada, mas deixaremos que o “EntityManager” tome conta do assunto.

Para começar precisamos fazer alguns downloads.

O primeiro será do MySQL.
O link para download é: http://dev.mysql.com/downloads/mysql/.

Imagem do Site MySQL

Basta instalar com padrão Microsoft: “Next, Next, Finish”. Apenas fique atento para a senha que você irá colocar no banco de dados. Ela será utilizada em nosso arquivo XML de configuração.

Precisamos criar um schema e para isso vamos abrir o “MySQL Command Line Client” que vai aparecer no seu menu do MySQL instalado.

Hibernate JPA

Digite o usuário e a senha colocados na hora da instalação. Digite o comando abaixo:

create database hello;

Aperte “Enter” e pronto.

Hibernate JPA

O próximo download será das bibliotecas do Hibernate 3 (aqui você poderá encontrar outras versões).

Vamos fazer o download do conector do MySQL (aqui você poderá escolher outro servidor para download).

O conector é o responsável por “ligar/intermediar” o Hibernate ao banco de dados. Estaremos utilizando o MySQL, mas caso queira fazer o teste com outro banco de dados basta fazer o download o conector do banco desejado.

API do Hibernate: Dentro do arquivo baixado encontraremos as bibliotecas do Hibernate 3, JPA 2 e algumas outras que são obrigatórias para o funcionamento do framework.
Após criar um projeto java do tipo “Java Project”, vamos criar criar um folder chamado “lib” para colocar as bibliotecas necessárias para funcionamento de nossa aplicação.

Iremos utilizar:

  • hibernate-distribution-3.6.0.Final/hibernate3.jar
  • hibernate-distribution-3.6.0.Final/lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar
  • hibernate-distribution-3.6.0.Final/lib/required/* ” (Todos os arquivos)

Atenção: Os arquivos da pasta “required” são obrigatórios. Copie todos os arquivos (inclusive os arquivos da pasta "required") listados acima para a pasta lib.

Conector MySQL: Assim como fizemos com o as bibliotecas do Hibernate faremos com o conector. Dentro do arquivo ZIP, que você baixou, existe uma biblioteca chamada “mysql-connector-java-5.1.14-bin.jar” basta copiá-la para dentro da pasta lib.

Ao final teremos os seguintes arquivos dentro da pasta lib:

Hibernate JPA

Precisamos criar um arquivo de configuração chamado “persistence.xml”. Esse arquivo é padrão do Hibernate e a pasta onde o arquivo deve estar obrigatoriamente é “src/META-INF”. Veja como nosso arquivo ficará (se você está lendo este tutorial mas já procurou em outras fontes e seu código não funciona, pode ser a declaração do “persistence.xml”. Alguns tutoriais apresentam um “header” inválido para ele):

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    
    <persistence-unit name="Hello" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/Hello"/>
            <property name="javax.persistence.jdbc.user" value="root" />
            <property name="javax.persistence.jdbc.password" value="root" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

Vou explicar qual a utilidade de cada linha do arquivo descrito acima:

  • <persistence-unit name=”Hello” transaction-type=”RESOURCE_LOCAL”>” Duas configurações importantes são definidas aqui. “unit name” define para a aplicação a configuração que será utilizada. No mesmo arquivo podemos ter vários tipos diferentes. “transaction-type” define como será nosso tipo de transação, em nosso caso “local”. Caso fosse uma aplicação web não iríamos precisar controlar a transação, o containner (JBoss, GlassFish, …) faria esse trabalho.
  • <provider>org.hibernate.ejb.HibernatePersistence</provider>” indica qual será o provider de nossa aplicação. Em nosso caso, o Hibernate.
  • hibernate.show_sql” habilita a exibição do SQL gerado no console.
  • javax.persistence.jdbc.driver” qual será o agente de conexão com o banco de dados que estaremos utilizando, vamos utilizar o MySQL.
  • javax.persistence.jdbc.url” a URL de nosso banco de dados juntamente com o schema de nosso banco de dados.
  • javax.persistence.jdbc.user” e “javax.persistence.jdbc.password” usuário e senha do banco de dados. Esses atributos foram definidos na instalação do MySQL. Utilizei os valores “root” e “root”.
  • hibernate.dialect” o dialeto que o Hibernate irá utilizar. Vamos discutir mais sobre essa opção em posts futuros, por exemplo, como gerar script do banco de dados de modo automático.
  • hibernate.hbm2ddl.auto” com essa opção ativada, o Hibernate atualizará suas tabelas quando necessário. Por exemplo, se a tabela não existir ela irá criar (“CREATE TABLE…”), se você adicionou uma coluna (“ALTER TABLE…”). Para testes vou deixar ativo, mas não aconselho a deixar essa opção ativada quando se trata de uma aplicação real. Não é uma boa escolha deixar essa alteração acontecer de modo automático em uma aplicação real. Deixe-a ativa apenas para teste local ou estudo.

Falta um último passo antes de começar a codificar. Adicionar as bibliotecas que baixamos ao build path do projeto. Precisamos fazer isso para que nossa aplicação as reconheça.

Botão direito do mouse em cima do projeto > “Properties > Java Build Path”.

Clique na aba Libraries e depois em “Add JARs”.

E por último, selecione os arquivos que estão dentro da pasta lib e click em Ok.

Finalmente vamos criar nossa classe “User” no package “com”. Com essa classe iremos realizar um CRUD (Create, Read, Update, Delete) básico.

package com;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="user")
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    
    @Column
    private String name;
    
    @Column
    private String password;
    
    @Override
    public boolean equals(Object obj) {
        if(obj instanceof User){
            User user = (User) obj;
            return user.getId() == this.getId();
        }
        
        return false;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Alguns detalhes sobre o código acima:

  • “@Entity” indica para nosso Provider que essa classe deve ser persistida em nosso banco de dados.
  • “@Table” define o nome da tabela a ser utilizada no banco de dados. Caso não tenha definida nenhum nome utilizando a chave “name”, o padrão será o nome exato da classe.
  • “@Id” mostra qual o nome do id de nossa classe.
  • “GeneratedValue” é a chave utilizada para que o valor do nosso id seja gerada por algum tipo de padrão. Em nosso exemplo estamos utilizando o tipo “AUTO”.
  • “@Column” define o atributo como uma coluna. Poderíamos também definir um nome pelo atributo “name”, como foi feito com a chave da tabela (“@Table”).

Por último precisamos de uma classe que irá criar a conexão com o banco de dados e gerenciar nossa classe de modelo User. Vamos criar uma classe chamada Main no package “com”.

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = new User();
            user.setName("abc123");
            user.setPassword("abc123");
            
            em.persist(user);
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

Alguns detalhes sobre o código acima:

  • Como estamos utilizando uma aplicação local precisamos controlar a conexão de modo manual. Por isso utilizamos o comando para abrir transação (“begin”), realizar commit e fechar a conexão (“close”).
  • Para informar que nosso objeto precisa ser salvo, utilizamos o comando “em.persist(user);”.

Basta executar nosso código e ver que a mensagem de execução com sucesso. Para confirmar, basta executar uma consulta em nosso banco de dados conforme imagens abaixo:

Hibernate JPA

Hibernate JPA

Note que, na imagem do console acima, o próprio Hibernate gerou o comando insert.

A grande vantagem do Hibernate é que ele traz um registro do banco de dados já como uma classe. E para fazer isso basta executar o código abaixo. Utilizamos o método “find” para localizar um registro do banco de dados pelo seu Id:

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = em.find(User.class, 1);
            
            System.out.println(user.getName());
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

E para realizar uma alteração? Vamos alterar o nome do nosso usuário, veja como é simples.

package com;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Hello");
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            User user = em.find(User.class, 1);
            
            user.setName("123abc");            
            
            em.getTransaction().commit();
        }
        catch (Exception e) {
            em.getTransaction().rollback();
            e.printStackTrace();
        }
        finally{
            emf.close();
        }
        
        System.out.println("It is over");
    }
}

Hibernate JPA

E para remover basta utilizar o comando remove implementado pela classe EntityManager. Basta realizar novamente o comando find e depois “em.remove(user)“.

Bem pessoal, o post foi longo, mas espero que possa ser útil.

Em um próximo post poderemos ver questões de relacionamentos e como fazer com que o Hibernate + Ant gere o script do banco de dados.

Qualquer dúvida ou comentário basta postar.
Até mais! o_

Review: João Luiz Silva Silvestre

Design Pattern – Strategy

Hello, how are you?

I will post here some design patterns of the study I am doing about this subject. The base book to this study will be Head First – Design Patterns. I will describe in here the same patterns that we can find in the book, but I will be using different samples and adding more material about this subject as soon it is possible.

Let us use this user case: “An internet site that sells toys cars is receiving a lot of customer visitors every day and becoming more famous. Its investors want more; they want that the site provides to the customers the simulations of the toy car actions.”

Check below our class model (there are others sub classes of ToyCar that are not described below):

Design Pattern - Strategy

The investors want that the car perform the action of starting the engine, to the customers may hear the engine sound. To accomplish this, the solution that it is “the most useful, fastest and quickest” may be to apply some changing in the super class. What of bad could come of using this solution that the Java gives us? Any change in the super class ToyCar will be reflected to all sub classes, and all sub classes will have the same behavior! We just have to create a method to start the engine (“startEngine()”) and our problem will be solved:

Design Pattern - Strategy

The team was very happy with the result of this new functionality that was delivered on time. Now the customers can hear the engine sound. BUT, after a phone call it was possible to see that something bad happened. One of the investors saw something in our application that should never happen, a wood car starting its engine. Why this happened? Let us see our model:

Design Pattern - Strategy

Our wood car, that also has ToyCar as super class, received the method to start the engine when a wood car does not have an engine. What could we do to solve this problem? We could just override the method:

    @Override
    public boolean startEngine() {
        // Do nothing
    }

Would the above code be the best solution? Let us suppose that we have a sub class of ToyCar, a metal car (“MetalCar”) where we would have to override the method too. By doing this method overriding in all classes methods we are increasing our project complexity. And each time, that a new ToyCar sub class is created and this sub class should not have the method startEngine() implemented, we would have to override this method also.

So, which solution would be the best one here? Let us apply the first pattern principle of this study:
“Identify everything that changes and isolate it from what does not change.”
What is the meaning of this? Think about an engine behavior that will be present in one class and other different engine behavior that should be present in another class; we could isolate this behavior from our ToyCar class. Instead of letting our class ToyCar handling this behavior, why do not delegate it? Here it come our second pattern principle:
“Program to an interface”
This principle is nothing more than: use all benefits from super class. Imagine if we have an interface with a visible method, our class will not care with which behavior the interface method has. Let us create an interface to handle this engine behavior:

Design Pattern - Strategy

Bellow you can check how our classes will be implemented. First the class ToyCar, then Mercedes and WoodCar:

// Interface and Engine Behavior implementations

public interface EngineBehavior {
    public boolean startEngine();
}

public class NoEngineBehavior implements EngineBehavior {

    @Override
    public boolean startEngine() {
        System.out.println("No engine to turn on");
        return true;
    }
}

public class RegularEngineBehavior implements EngineBehavior {

    @Override
    public boolean startEngine() {
        System.out.println("Engine On");
        return true;
    }
}

public class PowerfulEngineBehavior implements EngineBehavior {
    
    @Override
    public boolean startEngine() {
        System.out.println("Powerfull Engine On");
        return true;
    }
}

// Our Classes Implmentatioins
public class ToyCar {
    private int doorTotal;
    private int maxSpeed;
    protected EngineBehavior engineBehavior;
    // Others attributes
    
    public ToyCar(){
        engineBehavior = new RegularEngine();
    }
    
    public void startEngine(){
        engineBehavior.startEngine();
    }
    
    // Others methods
}

public class Mercedes extends ToyCar {
    
    public Mercedes(){
        engineBehavior = new PowerfulEngineBehavior();
    }
    
    @Override
    public void startEngine(){
        engineBehavior.startEngine();
    }    
}

public class WoodCar extends ToyCar {
    
    public WoodCar(){
        engineBehavior = new NoEngineBehavior();
    }
    
    @Override
    public void startEngine(){
        engineBehavior.startEngine();
    }
}

I know that we could change the way that our interface is receiving its implementation (“engineBehavior = new NoEngineBehavior();”) and another “upgrades” about patterns, but this refactoring is subject to another posts.

You may think: “Wait a minute, even if I do comment the method startEngine() or put the code engineBehavior = new NoEngineBehavior(); I still have “duplicated code” in my system!” Think with me about this next investor requirement: “When we call the method startEngine() in a type of ToyCar that does not have an engine, we would have to register this action in a log”. If you notice how our classes are implemented now (WoodCar, and all others MetalCar, BambooCar), we would have to change only the method startEngine() in our class NoEngineBehavior. All classes that do not have an engine behavior would be with a correct functioning.

Final considerations:

  • The class name should indicate a noun. Things like: “Car”, “House”, “Computer”, etc. In the user case that we simulated today this behavior is like our noun. It is a class that handles a behavior pattern.
  • Program to an interface – this principle does not necessarily means that we have to create an Interface, but it means always program to a super type. You should always program to a super type like a regular Class (POJO), Abstract Class and Interface. You must decide the best type for your system and implement it. In the book Head First – Design Patterns the authors make this explanation very clear. Do not mistake this principle that says: “always code for a super type” with “always create an interface”. A super type will be the best solution to your design problems in like 99% of the situations.
  • We just studied another project Principle:
    “Give priority to composition rather than inheritance”.

As we saw in our user case today, we used an interface to create the composition. Using composition in our system will make our job easier.

    Design Pattern: Strategy
    Studied Principles:

  • Identify everything that changes and isolate it from what does not change.
  • Program to an interface.
  • Give priority to composition rather than inheritance.

I hope this post might be able to help you.

If you have any questions or ideas to share just leave your comment.

See you soon.

Design Pattern – Strategy

Olá, tudo bem?

Vou aproveitar que estou estudando sobre design patterns e colocar aqui alguns padrões encontrados atualmente. O livro base é o Design Patterns – Head First. Vou descrever aqui os mesmos padrões encontrados no livro, mas estarei utilizando exemplos diferentes e acrescendo mais material na medida do possível.
Esse estudo para patterns serve para a certificação OCJD. Essa certificação exige a entrega de um sistema onde você deverá explicar o porquê de cada escolha sobre o seu design.

Vamos utilizar o seguinte caso de uso: “Um site de carros de brinquedos está recebendo bastantes visitas e se tornando famoso. Mas seus investidores querem mais, querem que agora seja possível fazer simulações das ações dos carros de brinquedo na web.”

Atualmente nosso modelo se divide da seguinte forma (existem várias outras subclasses de ToyCar que não foram descritas na imagem abaixo):

Design Pattern - Strategy

Agora os investidores desejam que todos os carros de brinquedo exerçam a função de ligar o motor, para que os clientes possam ouvir seu ronco. Para isso, a solução mais “simples, rápida e prática” teoricamente seria aplicar uma herança. Que mal há em utilizar esse ótimo artifício fornecido pelo Java? Basta criar o método ligar motor (“startEngine()”) em nosso modelo e tudo estará resolvido.

Design Pattern - Strategy

Após a entrega da nova funcionalidade, a equipe de desenvolvimento vibrava com o bom funcionamento ao ouvirem o ronco dos motores dos carros de brinquedo. MAS, uma ligação é recebida e um pequeno stress começa a aparecer. Um dos investidores ao navegar pela aplicação encontra algo que nunca deveria acontecer, um carro de madeira ligando motor. Por que isso aconteceu? Vejamos algo que passou despercebido:

Design Pattern - Strategy

Nosso carro de madeira, que também tem como superclasse a classe ToyCar, acabou por herdar essa função que não cabia a ele. O que fazer para resolver esse problema? Poderíamos sobrescrever o método herdado:

    @Override
    public boolean startEngine() {
        // Do nothing
    }

Seria essa a melhor saída? Supondo que temos uma classe para um carro de metal (“MetalCar”) também iríamos ter que sobrescrever esse método. Cada hora nosso projeto fica mais complexo, pois à medida que criarmos mais modelos de carros que não precisam ter o motor ligado, a sobrescrita do método de ligar o motor será obrigatória.

Qual outra solução seria possível aqui? Vamos aplicar um primeiro princípio a ser tratado nessa série de artigos:
Identifique tudo o que varia e separe do restante que não irá variar.”
O que isso significa? Veja que o comportamento de ligar motor pode ou não aparecer para determinadas classes, com isso poderíamos separar esse comportamento da nossa classe ToyCar. Ao invés de deixar nossa classe ToyCar controlando esse comportamento por que não delegamos essa função? Hora de ver, um segundo princípio de padrão de projeto:
Programe para interface.”
Esse conceito nada mais é do que: utilizar todo o benefício de herança. Imagine que se tivermos uma interface com um método conhecido, não iria fazer qualquer diferença para nossa classe qual a implementação de motor estiver sendo relacionada a ele. Vamos criar uma Interface para tratar o comportamento do motor?

Design Pattern - Strategy

E como ficariam nossas classes? Primeiramente a classe ToyCar, depois a classe Mercedes e por último, nossa classe carro de Madeira:

// Interface and Engine Behavior implementations

public interface EngineBehavior {
    public boolean startEngine();
}

public class NoEngineBehavior implements EngineBehavior {

    @Override
    public boolean startEngine() {
        System.out.println("No engine to turn on");
        return true;
    }
}

public class RegularEngineBehavior implements EngineBehavior {

    @Override
    public boolean startEngine() {
        System.out.println("Engine On");
        return true;
    }
}

public class PowerfulEngineBehavior implements EngineBehavior {
    
    @Override
    public boolean startEngine() {
        System.out.println("Powerfull Engine On");
        return true;
    }
}

// Our Classes Implmentatioins
public class ToyCar {
    private int doorTotal;
    private int maxSpeed;
    protected EngineBehavior engineBehavior;
    // Others attributes
    
    public ToyCar(){
        engineBehavior = new RegularEngine();
    }
    
    public void startEngine(){
        engineBehavior.startEngine();
    }
    
    // Others methods
}

public class Mercedes extends ToyCar {
    
    public Mercedes(){
        engineBehavior = new PowerfulEngineBehavior();
    }
    
    @Override
    public void startEngine(){
        engineBehavior.startEngine();
    }    
}

public class WoodCar extends ToyCar {
    
    public WoodCar(){
        engineBehavior = new NoEngineBehavior();
    }
    
    @Override
    public void startEngine(){
        engineBehavior.startEngine();
    }
}

Claro que poderíamos alterar o modo em que a Interface está recebendo sua classe implementada (“engineBehavior = new NoEngineBehavior();”) e outras questões relacionadas a patterns, mas isso será assunto para próximos artigos.

Talvez você possa pensar: “Espera aí, dá no mesmo se eu comentar o código “startEngine()” em todas as classes ou colocar o código engineBehavior = new NoEngineBehavior(); pois terei essa “repetição” em toda classe.” Pense comigo, e se ao chamar o método “startEngine()” para um tipo de ToyCar que não tenha motor, fosse necessário uma ação como registrar no log essa tentativa? Do modo como nossas classes estão implementadas, bastaria alterar o método da classe NoEngineBehavior e pronto. Todas nossas classes de carros que não tem motor já estarão com esse comportamento ativo.

Três considerações finais:

  • O nome de uma classe deve indicar um substantivo. Coisas em geral: “Carro”, “Casa”, “Computador”. Em nosso caso o comportamento (behavior) virou um substantivo. Ele é uma classe que determina um padrão de comportamento.
  • Programar para Interface: Não significa necessariamente criar sempre uma interface (“Interface”). Significa programar para um super tipo, ou seja, você poderia estar usando uma Classe normal, Classe Abstrata ou Interface. Você tem que adaptar sua necessidade à melhor opção possível. No livro do Use a Cabeça (Head First), os autores deixam isso claro. Não confundir esse conceito com sempre criar uma interface para qualquer situação, mas sim um super tipo que venha a solucionar o seu problema.
  • Acabamos por ver mais um princípio de projeto:
    "Dar prioridade à composição."

Como vimos no exemplo acima, colocamos nossa interface como composição, isso facilitou e muito nosso trabalho.
Padrão de Projeto: Strategy
Princípios vistos:

  • Identifique tudo o que varia e separe do restante que não irá variar.
  • Programe para interface.
  • Dar prioridade à composição.

Espero que esse post possa te ajudar. Qualquer dúvida ou colocação basta postar abaixo.

Até a próxima.
Revisores: João Luiz Silva Silvestre / Diego Prado

JSF – Hello World, Auto Complete

Hello, how are you?

Let us talk about a framework that is a precious helper as a web “front-end”: “JSF – Java Server Faces”.
We will see here a “Hello World” of JSF and in the end of this post, how to activate the Eclipse auto complete option. Notice that, except by the auto complete option, this tutorial can be done using just a notepad.
In case you have doubts about how to create a basic webserver you can check here: Creating a WebServer. There are others subjects here in this blog talking about webserver: Handling Exceptions on a WebApp, User Authentication (Filter/Servlet).

We need to start with some downloads:

Let us create a new Dynamic Web Project, adding Tomcat 6 as our server. If you have any doubts about how to install and configure the Tomcat, you can see a tutorial here: Creating a WebServer.

New Dynamic Project

We need to copy the “*.jar” files that we have downloaded from the internet to the folder “WebContent/WEB-INF/lib”. You will find the JSF Mojarra “*.jar” files at the path: “mojarra-2.0.3-FCS/lib”, inside the file you downloaded. After copy all the files, the folder must have these three files in lib folder: “jsf-api.jar”, “jsf-impl.jar” and “jstl-1.2.jar”.

Let us change the web.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

We have to create the faces-config.xml, but we will not use it.

<?xml version="1.0"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
      http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
   version="2.0">
  <!--
      Let's keep it empty. In JSF 2.0 we use annotations.
  -->
</faces-config>

It is time to create a class that will work as our controller. In this class we will put a welcome message. In a complete company system this message could be the user name, some message from a database, etc. Our class should be created in a package named “com” and will have the word “Hello” as its name.

package com;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class Hello {

    private final String youAreWelcome = "You finished a simple hello world. Let's navigate?";

    public String getYouAreWelcome() {
        return youAreWelcome;
    }
}

As our last action before the first test, we need to create our welcome page named “index.xhtml”:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hellow World JSF 2.0</title>
    </h:head>

    <h:body>
            <h:form>
                    <h:outputText value="#{hello.youAreWelcome}"/>
            </h:form>
    </h:body>
</html>

Pay attention to this: “Our page must be created inside WebContent folder”.

After adding our system to Tomcat, start it. To access our system we will use the link: http://localhost:8080/ProjectJSF/index.jsf. If you have any doubts about how to work with Tomcat Application, take a look at this link: Creating a WebServer. I’m doing this step by step while I am writing this tutorial, so if you did not see our first page without an error, go back and review your code.

Let us create some navigation in our system by doing a simple addition. To start with this change our Hello class will have three more fields to do the addition, another field will keep the user name.

package com;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class Hello {
    private String userName;
    private int valueA;
    private int valueB;
    private int total;

    private final String youAreWelcome = "You finished a simple hello world. Let's navigate?";

    public String getYouAreWelcome() {
        return youAreWelcome;
    }
    
    public String mathIt(){
        total = valueA + valueB;
        
        return "result.xhtml";
    }
    
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getValueA() {
        return valueA;
    }

    public void setValueA(int valueA) {
        this.valueA = valueA;
    }

    public int getValueB() {
        return valueB;
    }

    public void setValueB(int valueB) {
        this.valueB = valueB;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public int getTotal() {
        return total;
    }    
}

We will need to change our “index.xhtml” file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hellow World JSF 2.0</title>
    </h:head>

    <h:body>
            <h:form>
                <h:outputText value="#{hello.youAreWelcome}"/><br/>
                Your Name: <h:inputText id="userName" value="#{hello.userName}"/><br/>
                First Value: <h:inputText id="valueA" value="#{hello.valueA}"/><br/>
                Second Value: <h:inputText id="valueB" value="#{hello.valueB}"/><br/>
                  <h:commandButton value="Math It" title="Math It" action="#{hello.mathIt}"/>
            </h:form>
    </h:body>
</html>

The “result.xhtml” will be our last page to be created (it must be created in “WebContent” folder):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hellow World JSF 2.0</title>
    </h:head>

    <h:body>
        <h:form>
            Thanks for passing by: <h:outputText value="#{hello.userName}"/><br/>
            Total: <h:outputText value="#{hello.total}"/>
        </h:form>
    </h:body>
</html>

Accessing again our system using the link http://localhost:8080/ProjectJSF/index.jsf we will see that our work is complete.

An Eclipse resource that helps us a lot is the text auto complete. When I was creating this post, I noticed that JSF uses the file type “*.xhtml” and the text auto complete did not work with this file type. I found tons of solutions on the internet that work for some people and did not to others. I found a very simple solution that worked on each different computer that I tested. Right button click on the project and go to: “Properties > Project Facets”:Project properties Project Facetes Check the option “JavaServer Faces”, and it is done. Go to the “index” or “result” file and you will see the auto complete working. Project Facetes Autocompletar
In some future posts about JSF we will be talking about Ajax, validations, PrimeFaces, etc. This subject is huge.

I hope this post might help you.

If you want to comment or to ask about anything just post it.

See you later.