Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Criando uma aplicação passo a passo com Visual Web JavaServer Faces,
Spring 2.5 e Hibernate utilizando JPA
Após criar o banco de dados no MySQL e sua respectiva tabela (veja o quadro
“Executando instruções SQL pelo NetBeans”), volte ao NetBeans, na janela
Services, e com o botão direito do mouse sobre Databases selecione New
Connection. Em Basic setting>Name selecione MySQL (Connector/J driver).
Preencha Database URL com o acesso ao seu banco de dados e, em seguida, com o
nome de usuário e senha (veja Figura 5).
Figura 5. Criação de uma nova conexão com o banco de dados
Por fim, será necessário adicionar o driver JDBC do MySQL ao projeto. Com o botão
direito do mouse em Libraries, selecione Add Library>MySQL JDBC Driver>Add
Library.
Criando a entidade Contato
Sem aprofundar na JPA, para o exemplo, teremos apenas uma entidade, chamada
de Contato, que será criada por um assistente do NetBeans. Acesse File>New
File>Persistence>Entity Classes from Database e, na segunda etapa do assistente,
selecione New Data Source, em Data Source. A caixa de diálogo será semelhante à
Figura 6. Dê um nome qualquer em JNDI Name, uma vez que mais adiante esta
informação será substituída. Selecione a conexão que foi criada anteriormente em
Database Connection e confirme.
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
@Entity
@Table(name = "contato")
public class Contato implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "nome")
private String nome;
@Column(name = "email")
private String email;
@Column(name = "nascimento")
@Temporal(TemporalType.DATE)
private Date nascimento;
@Column(name = "telefone")
private String telefone;
Acessando os dados
Embora o Spring sempre tenha suportado o trabalho com persistência de dados por
outras tecnologias de mapeamento objeto-relacional (ORM), tal tarefa sempre
necessitou do conhecimento específico da biblioteca de persistência em questão. A
JPA melhora a portabilidade das aplicações, pois várias ferramentas ORM
implementam sua API padronizada. Além disso, a injeção de dependências permite
implementar o padrão DAO sem a necessidade de muitas classes, evitando o uso de
“fábricas” de objetos para isolar as implementações das interfaces.
Sobre o projeto, com o direito selecione New>Java Class. Preencha o nome da
classe ContatoDaoImp e o pacote javamagazine.dao. Altere a classe como
mostra a Listagem 4.
import java.util.List;
import javamagazine.entity.Contato;
import javax.persistence.*;
import org.springframework.transaction.annotation.*;
@Transactional(readOnly = true)
public class ContatoDaoImp {
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Transactional(readOnly = false)
public Contato save(Contato contato) {
this.entityManager.persist(contato);
return (Contato) contato;
}
@Transactional(readOnly = false)
public void delete(Contato contato) {
if (!this.entityManager.contains(contato)) {
contato = this.entityManager.merge(contato);
}
this.entityManager.remove(contato);
}
@Transactional(readOnly = false)
public void update(Contato contato) {
this.entityManager.merge(contato);
}
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="JavaMagazine" />
</bean>
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProces
sor" />
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="JavaMagazine" />
</bean>
<bean id="contatoDao"
class="javamagazine.dao.ContatoDaoImp">
</bean>
</beans>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
Para trabalhar com JPA, o Spring também fornece mais configurações. Caso queira
expandir mais adiante o exemplo, criando relacionamentos para outras entidades, é
importante entender que, como estamos trabalhando com o Hibernate, em alguns
casos você poderá utilizar a estratégia Lazy. Quando a aplicação termina de ler os
dados desta estratégia, a sessão é fechada, lançando uma exceção do tipo
LazyInitializationException caso alguma associação da entidade seja lida
posteriormente. Isso significa que temos de deixar a sessão do Hibernate aberta ou
inicializar todos os relacionamentos antes de renderizar a página. Ambas opções
podem causar problemas importantes de consumo de recursos do SGBD (como
conexões) ou de desempenho. Para evitar estes problemas, no Hibernate,
utilizamos um padrão chamado de "Open Session in View". Quando um servidor
web recebe uma requisição, esta é automaticamente filtrada pelo
Interceptador/Filtro, podendo executar qualquer código antes e depois da mesma.
Embora o exemplo deste artigo não trate de relacionamentos, muito menos sobre a
estratégia Lazy, é importante comentar que, no uso de JPA, teríamos que criar um
padrão semelhante para EntityManager1[1]. O Spring possui um filtro que
trabalha sobre este conceito, criando um padrão "Open EntityManager in View",
que deve ser configurado em web.xml, conforme o trecho mostrado:
<filter>
<filter-name>openEntityManager</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
</filter>
Como alguns desenvolvedores podem não gostar do uso de Filtros para esta tarefa,
o Spring também possui um interceptador que faz o mesmo processo. A diferença
entre os dois é que o interceptador roda no contêiner Spring e é configurado em
applicationContext.xml, conforme o trecho mostrado:
<bean name="openEntityManagerInViewInterceptor"
class="org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor
">
...
</bean>
Para este artigo, iremos utilizar o Filtro, como exemplo, onde na Listagem 6 é
exibida toda a configuração que deve ser adicionada em web.xml.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<filter>
<filter-name>openEntityManager</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>openEntityManager</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
O controle de acesso
O Facade ContatoController (veja Listagem 7) é a classe responsável pela lógica
de negócios, delegando chamadas à camada de acesso a dados e controle
transacional. Este controle de transações será administrado pelo Spring, através da
injeção no atributo contatoDao. Esta classe terá a injeção do Spring no managed
bean para trabalhar com o JavaServer Faces.
import java.util.List;
import javamagazine.dao.ContatoDao;
import javamagazine.entity.Contato;
<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>
import com.sun.rave.web.ui.appbase.AbstractSessionBean;
import javamagazine.controller.ContatoController;
import javamagazine.entity.Contato;
import javax.faces.FacesException;
todosContatos();
}
//array de Contato
private Contato[] contatos;
Desenvolvendo a página
O Visual Web JSF possui diversos componentes que podem ser acessados através
da janela Palette. Se você já trabalhou com ferramentas visuais como Delphi, Visual
Studio .NET ou até mesmo com o próprio editor visual de aplicações Swing do
NetBeans, perceberá que o Visual Web JSF é semelhante. A Figura 11 representa
o resultado final do desenho da página, cuja criação explicamos passo a passo a
seguir.
Figura 11. Desenho da aplicação
Exibindo os contatos
Para exibir os contatos, utilizaremos o componente Table, que será arrastado para
a página abaixo do formulário criado, conforme a Figura 11.
Com o botão direito do mouse, selecione Table Layout no menu de contexto. Na
caixa de diálogo (veja Figura 12), altere para contatos em Get Data From. Caso
esta opção não esteja sendo exibida, faça o “build” na classe SessionBean1.
Figura 12. Definindo o layout da tabela
Ao mesmo tempo, se colocar em JSP, verá que também foi adicionado o atributo
actionExpression="#{Expressão}" em <webuijsf:hyperlink>. Isso significa
que ao clicar no link Editar, automaticamente você invocará os eventos
determinados no método hyperlink1_action(). No Design, podemos ver em
Properties>Events>action.
No NetBeans 6.1, alguns passos a mais serão necessários para trabalhar com os
componentes que estamos utilizando neste exemplo. Clique com o direito do
mouse, na janela Navigator, em table1>tableRowGroup1 e selecione Add Binding
Attribute no menu de contexto. O mesmo deverá ser feito para os TextFields:
nome, email, telefone e nascimento.
Retornando para Java, adicione o código da Listagem 10 para o link Editar do
componente Table.
Retorne para o Design e dê um duplo clique agora sobre o link Excluir da tabela.
Adicione o código da Listagem 11. Em seguida, faça o mesmo procedimento com
o botão Salvar do formulário e altere como na Listagem 12.
return null;
}
Conclusões
Neste artigo foi mostrado que o Visual Web JSF possui flexibilidade para trabalhar
com outros frameworks, através de um exemplo prático utilizando o Spring, o
Hibernate e a JPA.
Aprendemos também que o Spring Framework, suportado mais facilmente pelo
NetBeans através de um plugin, simplificou seu desenvolvimento com anotações,
integrando suavemente com a JPA, com pouca escrita em arquivo XML.
Um fator importante no trabalho com Visual Web JSF é sua facilidade de desenhar
aplicações JavaServer Faces, com componentes arrastáveis no estilo WYSIWYG, o
que poupa muito trabalho do desenvolvedor. Embora suas configurações sejam
visuais, compreender a estrutura do JavaServer Faces para trabalhar com o Visual
Web JSF é importantíssimo, mesmo tendo a grande maioria de seus componentes
específicos à ferramenta.
Vimos também que é simples integrar o Visual Web a outras tecnologias, mesmo as
que carecem de suporte direto. Assim, você não fica limitado a usar componentes,
bibliotecas ou frameworks que sejam suportados “de fábrica” pelo Visual Web –
mesmo o desenvolvimento visual pode ser habilitado para componentes de
terceiros.