blob: 576dceb31f8c246eef7a44d3169cc4965b0203f9 [file] [log] [blame]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
= Utilizando o Hibernate em uma Aplicação Web
:jbake-type: tutorial
:jbake-tags: tutorials
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: Utilizando o Hibernate em uma Aplicação Web - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, Utilizando o Hibernate em uma Aplicação Web
Neste tutorial, você utiliza o NetBeans IDE para criar e implantar uma aplicação Web que exibe dados do banco de dados. A aplicação Web utiliza o framework do Hibernate como a camada de persistência para recuperar e armazenar objetos Java simples antigos (POJOs) em um banco de dados relacional.
O Hibernate é o framework que fornece ferramentas para o mapeamento relacional de objeto (ORM). O tutorial demonstra como adicionar suporte para o framework do Hibernate ao IDE e criar os arquivos necessários do Hibernate. Depois de criar os objetos Java e configurar a aplicação para utilizar o Hibernate, você cria um bean gerenciado pelo JSF e páginas do JSF 2.0 para exibir dados.
Antes de começar este tutorial, você pode se familiarizar com os seguintes documentos.
* Documentação do Hibernate em link:http://www.hibernate.org/[+hibernate.org+]
* link:quickstart-webapps.html[+Introdução ao Desenvolvimento de Aplicações Web+]
* link:jsf20-intro.html[+Introdução ao JavaServer Faces 2.x+]
image::images/netbeans-stamp-74-73-72.png[title="O conteúdo desta página se aplica ao NetBeans IDE 7.2, 7.3 e 7.4"]
*Para seguir este tutorial, são necessários os recursos e o software a seguir.*
|===
|Software ou Recurso |Versão Necessária
|link:https://netbeans.org/downloads/index.html[+NetBeans IDE+] |Versões 7.1, 7.2, 7.3 e 7.4 do Java EE
|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+JDK (Java Development Kit)+] |Versão 6 ou 7
|GlassFish Server Open Source Edition |3.x ou 4.x
|link:http://www.mysql.com/[+Servidor de banco de dados MySQL+] |Versão 5.x
|Banco de Dados Sakila |Plug-in disponível na Central de Atualização
|===
Você pode fazer download link:https://netbeans.org/projects/samples/downloads/download/Samples/JavaEE/DVDStoreEE6.zip[+de um arquivo compactado zip do projeto finalizado+].
== Criando o Banco de Dados
Este tutorial utiliza um banco de dados MySQL chamado ``sakila`` , uma amostra gratuita do banco de dados MySQL que está disponível no site do MySQL. O banco de dados sakila não está incluído quando você instala o IDE, portanto, você precisa primeiro criar o banco de dados para seguir este tutorial.
Para criar o banco de dados sakila, você pode fazer o download e instalar o plug-in Banco de Dados de Amostra do Sakila usando o Gerenciador de plug-ins. Depois que você instala o plug-in, o banco de dados sakila é adicionado à lista de bancos de dados na caixa de diálogo Criar banco de dados MySQL.
Para obter mais informações sobre a configuração do IDE para trabalhar com o MySQL, consulte o tutorial link:../ide/mysql.html[+Estabelecendo Conexão com um Banco de Dados MySQL+].
1. Abra o Gerenciador de plug-ins e instale o plug-in Banco de Dados de Amostra do Sakila.
2. Depois da instalação do plug-in, inicie o banco de dados MySQL expandindo o nó Bancos de Dados na janela Serviços, clicando com o botão direito do mouse no nó Servidor MySQL e selecionando Iniciar.
3. Clique com o botão direito do mouse no nó Servidor MySQL e escolha Criar Banco de Dados.
4. Selecione o banco de dados Sakila na lista drop-down Novo Nome de Banco de Dados, na caixa de diálogo Criar Banco de Dados MySQL. Clique em OK.
image::images/create-sakila-mysql.png[title="Tela da caixa de diálogo Criar Banco de Dados MySQL"]
Quando você clicar em OK, um nó do Salkila será exibido sob o nó Servidor MySQL.
. Clique com o botão direito do mouse no nó do Sakila e escolha Conectar.
Quando você clicar em Conectar, um nó de conexão do banco de dados do banco de dados Sakila ( ``jdbc:mysql://localhost:3306/sakila [_nome de usuário_ em Default]`` ) será apresentado no nó Bancos de Dados. Quando uma conexão for aberta, você poderá exibir os dados no banco de dados ampliando o nó de conexão.
== Criando o Projeto de Aplicação Web
Neste exercício, você criará um projeto de aplicação Web e adicionará as bibliotecas do Hibernate ao projeto. Após criar o projeto, você selecionará Hibernate no painel Frameworks do assistente de Novo Projeto e especificará o banco de dados.
1. Escolha Arquivo > Novo Projeto (Ctrl-Shift-N; &#8984-Shift-N no Mac) no menu principal. Selecione Aplicação Web na categoria Java Web e clique em Próximo.
2. Digite *DVDStore* para o nome do projeto e defina a localização do projeto.
3. Desmarque a opção Usar Pasta Dedicada, se ela estiver selecionada. Clique em Próximo.
Neste tutorial, não é necessário copiar as bibliotecas do projeto para uma pasta dedicada, pois você não precisará compartilhar bibliotecas com outros usuários.
. Defina o servidor como GlassFish Server e defina a versão do Java EE para Java EE 6 Web ou Java EE 7 Web. Clique em Próximo.
. Marque a caixa de seleção JavaServer Faces e utilize as bibliotecas default do JSF 2.x.
. Marque a caixa de seleção Hibernar na lista de frameworks.
. Selecione o banco de dados sakila na lista drop-down Conexão de Banco de Dados. Clique em Finalizar.
*Observação:* se o banco de dados sakila não estiver disponível como uma opção no painel Framework do assistente, verifique se a conexão está listada no nó Bancos de Dados da janela Serviços. Se a conexão não existir, será necessário criar a conexão do banco de dados.
image::images/hib-newwebapp.png[title="Painel Frameworks do assistente de Novo Projeto mostrando como adicionar o suporte do Hibernar ao projeto"]
Quando você clicar em Finalizar, o IDE criará o projeto de aplicação Web e abrirá o arquivo ``hibernate.cfg.xml`` e ``index.xhtml`` no editor.
Se expandir o nó Bibliotecas na janela Projetos, você poderá ver que o IDE adicionou as bibliotecas do Hibernate ao projeto.
image::images/hib-libraries.png[title="Tela da janela Projetos mostrando bibliotecas do Hibernate"]
== Modificando o Arquivo de Configuração do Hibernate
Quando você cria um novo projeto que utiliza o framework do Hibernate, o IDE cria automaticamente o arquivo de configuração ``hibernate.cfg.xml`` na raiz do classpath de contexto da aplicação (na janela Arquivos, ``src/java`` ). O arquivo está localizado em ``<pacotes default>`` no nó Pacotes de Código-Fonte na janela Projetos. O arquivo de configuração contém informações sobre a conexão do banco de dados, os mapeamentos de recursos e outras propriedades da conexão. É possível editar o arquivo utilizando o editor de várias views ou editar o XML diretamente no editor XML.
Neste exercício, você editará as propriedades default especificadas em ``hibernate.cfg.xml`` para ativar o log de depuração das instruções SQL e para ativar o gerenciamento de contexto de sessão do Hibernate.
1. Abra ``hibernate.cfg.xml`` na guia Desenho. Você pode abrir o arquivo expandindo o nó ``<pacotes default>`` em Pacotes de Códigos-Fonte na janela Projetos e clicando duas vezes em ``hibernate.cfg.xml`` .
2. No editor XML com várias views, expanda o nó Propriedades da Configuração em Propriedades Opcionais.
3. Clique em Adicionar para abrir a caixa de diálogo Adicionar Propriedade do Hibernate.
4. Na caixa de diálogo, selecione a propriedade ``hibernate.show_sql`` e defina o valor para ``true`` . Isso ativa o log de depuração das instruções SQL.
image::images/add-property-showsql.png[title="Caixa de diálogo Adicionar Propriedade Hibernate que mostra o valor de definição de hibernate.show_sql"]
. Expanda o nó Propriedades Diversas e clique em Adicionar.
. Na caixa de diálogo, selecione ``properties hibernate.current_session_context_class`` e defina o valor para ``thread`` para ativar o gerenciamento de contexto automático da sessão do Hibernate.
image::images/add-property-sessioncontext.png[title="Adicione a caixa e diálogo Propriedade do Hibernate mostrando como definir o valor da propriedade hibernate.current_session_context_class"]
. Clique novamente em Adicionar no nó Propriedades Diversas e selecione ``hibernate.query.factory_class`` na lista drop-down Nome da Propriedade.
. Selecione *org.hibernate.hql.classic.ClassicQueryTranslatorFactory* como o Valor da Propriedade. Clique em OK.
image::images/add-property-factoryclass.png[title="Caixa de diálogo Adicionar Propriedade Hibernate que mostra o valor de definição de hibernate.query.factory_class"]
Se clicar na guia XML no editor, você pode ver o arquivo na view XML. O arquivo deve ter uma aparência semelhante à seguinte (as três novas propriedades estão em negrito):
[source,xml]
----
<hibernate-configuration>
<session-factory name="session1">
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sakila</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">######</property>
*<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>*
</session-factory>
</hibernate-configuration>
----
. Salve as alterações feitas no arquivo.
Você pode fechar o arquivo, pois não será necessário editá-lo novamente.
== Criando o Arquivo de Ajuda ``HibernateUtil.java``
Para usar o Hibernate, é necessário criar uma classe de ajuda que lide com a inicialização e que acesse o ``SessionFactory`` do Hibernate para obter um objeto de Sessão. A classe chama ``configure()`` , carrega o arquivo de configuração ``hibernate.cfg.xml`` e cria ``SessionFactory`` para obter o objeto Sessão.
Nesta seção, você usa o assistente para Novo Arquivo a fim de criar a classe helper ``HibernateUtil.java`` .
1. Clique com o botão direito do mouse no nó dos Pacote de Códigos-fonte e selecione Novo > Outro para abrir o assistente para Novo Arquivo.
2. Selecione Hibernate na lista Categorias e HibernateUtil.java na lista Tipos de Arquivo. Clique em Próximo.
3. Digite *HibernateUtil* para o nome da classe e *dvdrental* para o pacote. Clique em Finalizar.
image::images/hibernate-util-wizard.png[title="Tela do assistente do HibernateUtil"]
Quando você clicar em Finalizar, o ``HibernateUtil.java`` será aberto no editor. Você pode fechar o arquivo porque não precisa editá-lo.
== Gerando Arquivos de Mapeamento Hibernate e Classes Java
Neste tutorial, você utilizará um POJO (objetos Java simples antigos) para representar os dados em cada uma das tabelas do banco de dados a ser utilizado. A classe Java especifica os campos das colunas nas tabelas e utiliza setters e getters simples para recuperar e gravar os dados. Para mapear os POJOs para as tabelas, utilize um arquivo de mapeamento do Hibernate ou utilize anotações na classe.
Você pode utilizar os Arquivos de Mapeamento do Hibernate e POJOs obtidos de um assistente de Banco de Dados para criar vários POJOs e arquivos de mapeamento com base nas tabelas de banco de dados. Ao utilizar o assistente, selecione todas as tabelas para as quais deseja POJOs e arquivos de mapeamento, e o IDE irá gerar os arquivos com base nas tabelas do banco de dados e adicionar as entradas de mapeamento no ``hibernate.cfg.xml`` . Quando usa o assistente, você pode escolher os arquivos que deseja que o IDE gere (somente os POJOs, por exemplo) e selecionar as opções de geração de código (gerar código que use anotações EJB 3, por exemplo).
*Observação.* O IDE também possui assistentes para ajudá-lo a criar POJOs e arquivos de mapeamento individuais do zero.
=== Criando o Arquivo de Engenharia Reversa do Hibernate
Se quiser utilizar os arquivos de Mapeamento do Hibernate e POJOs de um assistente de Banco de Dados, primeiro é necessário criar um arquivo de engenharia reversa ``hibernate.reveng.xml`` . Os Arquivos de Mapeamento do Hibernate e POJOs de um assistente de Banco de Dados requerem os arquivos ``hibernate.reveng.xml`` e ``hibernate.cfg.xml`` .
O arquivo de engenharia reversa permite ter maior controle sobre a estratégia de mapeamento do banco de dados. O Assistente para Engenharia Reversa do Hibernate cria um arquivo de engenharia reversa com uma configuração default que pode ser editada no editor XML.
Para criar o arquivo de engenharia reversa do Hibernate, execute as etapas seguintes.
1. Clique com o botão direito do mouse no nó Pacotes de Código-fonte na janela Projetos e escolha Novo > Outro para abrir o assistente para Novo Arquivo.
2. Selecione o Assistente para Engenharia Reversa do Hibernate na categoria Hibernate. Clique em Próximo.
3. Especifique ``hibernate.reveng`` como o Nome do arquivo e ``src/java`` para a Pasta. Clique em Próximo.
4. Selecione ``hibernate.cfg.xml`` na lista drop-down Arquivo de Configuração, caso não esteja selecionado.
5. Selecione as tabelas a seguir em Tabelas Disponíveis e clique em Adicionar para adicionar as tabelas a Tabelas Selecionadas.
* ator
* categoria
* filme
* film_actor
* film_category
* idioma
Clique em Finalizar.
image::images/hibernate-reveng-wizard.png[title="Novo assistente de Engenharia Reversa do Hibernate"]
O assistente gera um arquivo de engenharia reversa ``hibernate.reveng.xml`` e abre o arquivo no editor. Você pode fechar o arquivo de engenharia reversa porque não precisará editar o arquivo.
Para obter mais detalhes sobre como trabalhar com o arquivo ``hibernate.reveng.xml`` , consulte o link:http://docs.jboss.org/tools/2.1.0.Beta1/hibernatetools/html/reverseengineering.html[+Capítulo 5. Controlando a engenharia reversa+] no link:http://docs.jboss.org/tools/2.1.0.Beta1/hibernatetools/html/[+Guia de Referência das Ferramentas do Hibernate+].
=== Criando arquivos de mapeamento do Hibernate e POJOs
Você pode utilizar os Arquivos de Mapeamento do Hibernate e POJOs obtidos de um assistente de Banco de Dados para gerar arquivos. O assistente pode gerar um POJO e um arquivo de mapeamento correspondente para cada tabela que você selecionar no assistente. Os arquivos de mapeamento são arquivos XML que contêm dados sobre como as colunas das tabelas são mapeadas para os campos nos POJOs. É necessário ter os arquivos ``hibernate.reveng.xml`` e ``hibernate.cfg.xml`` para utilizar o assistente.
Para criar os POJOS e arquivos de mapeamento utilizando um assistente, execute as etapas a seguir:
1. Clique com o botão direito do mouse no nó Pacotes de Código-fonte na janela Projetos e escolha Novo > Outro para abrir o assistente para Novo Arquivo.
2. Selecione Arquivos de Mapeamento do Hibernate e POJOs provenientes de um Banco de Dados na categoria Hibernate. Clique em Próximo.
3. Certifique-se de que os arquivos ``hibernate.cfg.xml`` e ``hibernate.reveng.xml`` estejam selecionados nas listas drop-down.
4. Selecione *Funcionalidades da Linguagem JDK 5* nas opções Definições Gerais.
5. Certifique-se de que as opções *Código do Domínio* e *Mapeamentos XML do Hibernate* estejam selecionadas.
6. Selecione *dvdrental* para o Nome do pacote. Clique em Finalizar.
image::images/hibernate-pojo-wizard2.png[title="Gerar assistente Arquivos de Mapeamento Hibernar e POJOs"]
Quando você clicar em Finalizar, o IDE irá gera POJOs e arquivos de mapeamento do Hibernate com os campos mapeados para as colunas especificadas em ``hibernate.reveng.xml`` . O IDE também adicionará entradas de mapeamento em ``hibernate.cfg.xml`` .
[source,xml]
----
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sakila</property>
<property name="hibernate.connection.username">myusername</property>
<property name="hibernate.connection.password">mypassword</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
<mapping resource="dvdrental/FilmActor.hbm.xml"/>
<mapping resource="dvdrental/Language.hbm.xml"/>
<mapping resource="dvdrental/Film.hbm.xml"/>
<mapping resource="dvdrental/Category.hbm.xml"/>
<mapping resource="dvdrental/Actor.hbm.xml"/>
<mapping resource="dvdrental/FilmCategory.hbm.xml"/>
</session-factory>
</hibernate-configuration>
----
*Observação.* Confirme se os elementos ``mapping`` serão listados após os elementos ``property`` no arquivo ``hibernate.cfg.xml`` .
É possível expandir o pacote ``dvdrental`` para ver os arquivos gerados pelo assistente.
image::images/hib-projectswindow.png[title="Janela Projetos mostrando os POJOs gerados"]
Você pode utilizar o assistente para mapeamento do Hibernate se quiser criar um arquivo de mapeamento do Hibernate que mapeie uma tabela específica para uma classe específica.
Para obter mais detalhes sobre como trabalhar com o arquivo ``hibernate.reveng.xml`` , consulte o link:http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html[+Capítulo 5. Mapeamento O/R Básico+] da link:http://docs.jboss.org/hibernate/stable/core/reference/en/html/[+Documentação de Referência do Hibernate+].
== Criando a Classe do Helper ``FilmHelper.java``
Agora você criará uma classe do helper no pacote ``dvdrental`` que será utilizada para efetuar consultas do Hibernate no banco de dados. Você utilizará o editor HQL (Hibernate Query Language) para criar e testar as consultas para recuperar dados. Depois de testar as consultas, você criará criados métodos na classe do helper que criarão e executarão as consultas. Em seguida, você chamará os métodos na classe do helper de um bean gerenciado pelo JSF.
=== Criando a Classe
Nesta seção, utilize o assistente de Novo Arquivo para criar a classe do helper ``FilmHelper.java`` no pacote ``dvdrental`` . Você criará uma sessão do Hibernate, chamando ``getSessionFactory`` em ``HibernateUtil.java`` e criará alguns métodos do helper para fazer consultas e recuperar dados do banco de dados. Você chamará os métodos do helper de páginas JSP.
1. Clique com o botão direito do mouse no nó do pacote de códigos-fonte ``dvdrental`` e selecione Novo > Classe Java para abrir o assistente de Novo arquivo.
2. Digite *FilmHelper* como nome da classe.
3. Confirme se *dvdrental* está selecionado como o Pacote. Clique em Finalizar.
4. Adicionando o código a seguir (em negrito) para criar uma sessão do Hibernate.
[source,java]
----
public class FilmHelper {
*Session session = null;
public FilmHelper() {
this.session = HibernateUtil.getSessionFactory().getCurrentSession();
}*
}
----
. Clique com o botão direito do mouse no editor, selecione Corrigir importações (Alt-Shift-I; &amp;#8984-Shift-I no Mac) para adicionar as instruções necessárias de importação ( ``org.hibernate.Session`` ) e salve suas alterações.
Agora você modificará ``FilmHelper.java`` para adicionar métodos de consulta do BD.
=== Enumerando Títulos de Filmes e Recuperando Atores Utilizando uma Consulta HQL
Neste exercício, você criará uma consulta HQL (Hibernate Query Language) que consulta o banco de dados para recuperar uma lista de títulos de filmes da tabela Film. Em seguida, você adicionará um método que consulte as tabelas Actor e Film_actor para extrair os atores que atuam em um filme específico.
A tabela Film possui 1000 registros, de modo que o método para recuperar a lista de filmes deveria ser capaz de recuperar os registros com base na chave primária ``filmId`` . Utilize o editor HQL para criar e testar a consulta HQL. Após criar a consulta correta, você adicionará um método à classe que possa gerar a consulta apropriada.
1. Clique com o botão direito do mouse no nó do projeto na janela Projetos e selecione Limpar e Construir.
2. Clique com o botão direito do mouse em ``hibernate.cfg.xml`` na janela Projetos e selecione Executar Consulta HQL para abrir o editor de consultas HQL.
3. Selecione hibernate.cfg na lista drop-down da barra de ferramentas.
4. Teste a conexão digitando no editor e clicando no botão Executar a Consulta HQL image:images/run_hql_query_16.png[title="Botão Executar Consulta HQL"] ) da barra de ferramentas.
[source,java]
----
from Film
----
Ao clicar em Executar a Consulta HQL, você verá os resultados da consulta na janela inferior do editor de consultas HQL.
image::images/hibernate-hqleditor1.png[title="Gerar assistente Arquivos de Mapeamento Hibernar e POJOs"]
Se você clicar no botão SQL, você verá a consulta SQL equivalente.
[source,java]
----
select film0_.film_id as col_0_0_ from sakila.film film0_
----
. Digite a consulta a seguir para recuperar os registros da tabela Film, onde o id do filme está entre 100 e 200.
[source,java]
----
from Film as film where film.filmId between 100 and 200
----
A janela de resultados exibirá uma lista de registros. Agora que você verificou que a consulta testada retorna os resultados desejados, utilize a consulta na classe do helper.
. Adicione o método a seguir, ``getFilmTitles`` a ``FilmHelper.java`` , para recuperar os filmes, onde o id do filme está entre uma determinada faixa especificada pelas variáveis ``startID`` e ``endID`` .
[source,java]
----
public List getFilmTitles(int startID, int endID) {
List<Film> filmList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery ("from Film as film where film.filmId between '"+startID+"' and '"+endID+"'");
filmList = (List<Film>) q.list();
} catch (Exception e) {
e.printStackTrace();
}
return filmList;
}
----
. Adicione o método a seguir, ``getActorsByID`` , para recuperar os atores de um filme específico. O método construirá a consulta utilizando ``filmId`` como a variável de entrada.
[source,java]
----
public List getActorsByID(int filmId){
List<Actor> actorList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery ("from Actor as actor where actor.actorId in (select filmActor.actor.actorId from FilmActor as filmActor where filmActor.film.filmId='" + filmId + "')");
actorList = (List<Actor>) q.list();
} catch (Exception e) {
e.printStackTrace();
}
return actorList;
}
----
. Corrija as importações e salve as alterações.
Ao corrigir suas importações, selecione ``java.util.List`` e ``org.hibernate.Query`` .
=== Adicionando Métodos Adicionais do Helper
Agora você adicionará métodos adicionais do assistente que criem consultas com base em uma variável de entrada. É possível verificar as consultas no editor de consultas HQL.
1. Adicione o método a seguir para recuperar uma lista de categorias de acordo com ``filmId`` .
[source,java]
----
public Category getCategoryByID(int filmId){
List<Category> categoryList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery("from Category as category where category.categoryId in (select filmCat.category.categoryId from FilmCategory as filmCat where filmCat.film.filmId='" + filmId + "')");
categoryList = (List<Category>) q.list();
} catch (Exception e) {
e.printStackTrace();
}
return categoryList.get(0);
}
----
. Adicione o método seguinte para recuperar um único filme de acordo com o ``filmId`` .
[source,java]
----
public Film getFilmByID(int filmId){
Film film = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery("from Film as film where film.filmId=" + filmId);
film = (Film) q.uniqueResult();
} catch (Exception e) {
e.printStackTrace();
}
return film;
}
----
. Adicione o método a seguir para recuperar o idioma do filme de acordo com o ``filmId`` .
[source,java]
----
public String getLangByID(int langId){
Language language = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery("from Language as lang where lang.languageId=" + langId);
language = (Language) q.uniqueResult();
} catch (Exception e) {
e.printStackTrace();
}
return language.getName();
}
----
. Salve as alterações.
== Criando o Bean Gerenciado pelo JSF
Neste exercício, você criará um bean gerenciado pelo JSF. Os métodos do bean gerenciado são utilizados para exibir dados nas páginas JSF e para acessar métodos da classe do helper para recuperar registros. A especificação do JSF 2.0 permite utilizar anotações em uma classe bean para identificar a classe como um bean gerenciado pelo JSF, especificar o escopo e um nome para o bean.
Para criar o bean gerenciado, execute as seguintes etapas:
1. Clique com o botão direito do mouse no nó do pacote de código-fonte ``dvdrental`` e selecione Novo > Outro.
2. Selecione Bean Gerenciado pelo JSF na categoria JavaServer Faces. Clique em Próximo.
3. Digite *FilmController* para Nome da Classe.
Você usará o nome ``filmController`` do Bean Gerenciado como o valor para ``inputText`` e ``commandButton`` na página JSF ``index.xhtml`` ao chamar métodos no Bean.
. Selecione *dvdrental* para o Pacote.
. Digite *filmController* como o Nome que será utilizado para o bean gerenciado.
. Defina o Escopo Como Sessão. Clique em Finalizar.
image::images/hib-newmanagedbean.png[title="Novo assistente de Bean Gerenciado pelo JSF"]
Quando você clicar em Finalizar, o IDE gerará a classe bean e abrirá a classe no editor. O IDE adicionou as anotações ``@ManagedBean`` e ``@SessionScoped`` .
[source,java]
----
@ManagedBean
@SessionScoped
public class FilmController {
/** Creates a new instance of FilmController */
public FilmController() {
}
}
----
*Observação.* Observe que o nome do bean gerenciado não está especificado explicitamente. Por default, o nome do bean é o mesmo que o nome da classe e inicia com letra minúscula. Se você quiser que o nome do bean seja diferente do nome da classe, você poderá especificá-lo explicitamente como um parâmetro das anotações ``@ManagedBean`` (por exemplo, ``@ManagedBean(name="myBeanName")`` .
1. Adicione os campos a seguir (em negrito) à classe.
[source,java]
----
@ManagedBean
@SessionScoped
public class FilmController {
*int startId;
int endId;
DataModel filmTitles;
FilmHelper helper;
private int recordCount = 1000;
private int pageSize = 10;
private Film current;
private int selectedItemIndex;*
}
----
. Adicione o código a seguir (em negrito) para criar a instância do FilmController e recuperar os filmes.
[source,java]
----
/** Creates a new instance of FilmController */
public FilmController() {
*helper = new FilmHelper();
startId = 1;
endId = 10;
}
public FilmController(int startId, int endId) {
helper = new FilmHelper();
this.startId = startId;
this.endId = endId;
}
public Film getSelected() {
if (current == null) {
current = new Film();
selectedItemIndex = -1;
}
return current;
}
public DataModel getFilmTitles() {
if (filmTitles == null) {
filmTitles = new ListDataModel(helper.getFilmTitles(startId, endId));
}
return filmTitles;
}
void recreateModel() {
filmTitles = null;
}*
----
. Adicione os métodos a seguir usados para exibir a tabela e navegar entre as páginas.* public boolean isHasNextPage() {
if (endId + pageSize <= recordCount) {
return true;
}
return false;
}
public boolean isHasPreviousPage() {
if (startId-pageSize > 0) {
return true;
}
return false;
}
public String next() {
startId = endId+1;
endId = endId + pageSize;
recreateModel();
return "index";
}
public String previous() {
startId = startId - pageSize;
endId = endId - pageSize;
recreateModel();
return "index";
}
public int getPageSize() {
return pageSize;
}
public String prepareView(){
current = (Film) getFilmTitles().getRowData();
return "browse";
}
public String prepareList(){
recreateModel();
return "index";
}
*
Os métodos que retornam "index" ou "browse" solicitarão o handler de navegação JSF para tentar abrir uma página denominada ``index.xhtml`` ou ``browse.xhtml`` . A especificação JSF 2.0 permite a utilização de regras de navegação implícitas em aplicações que utilizam a tecnologia Facelets. Nesta aplicação, não há regras de navegação configuradas em ``faces-config.xml`` . Em vez disso, o handler de navegação tentará localizar a página adequada na aplicação.
. Adicione os métodos a seguir que acessam a classe do helper para recuperar detalhes adicionais do filme.* public String getLanguage() {
int langID = current.getLanguageByLanguageId().getLanguageId().intValue();
String language = helper.getLangByID(langID);
return language;
}
public String getActors() {
List actors = helper.getActorsByID(current.getFilmId());
StringBuffer totalCast = new StringBuffer();
for (int i = 0; i < actors.size(); i++) {
Actor actor = (Actor) actors.get(i);
totalCast.append(actor.getFirstName());
totalCast.append(" ");
totalCast.append(actor.getLastName());
totalCast.append(" ");
}
return totalCast.toString();
}
public String getCategory() {
Category category = helper.getCategoryByID(current.getFilmId());
return category.getName();
}*
[source,java]
----
----
. Corrija as importações (Ctrl-Shift-I) e salve as alterações.
Você pode utilizar a funcionalidade para autocompletar código no editor para ajudar a digitar seu código.
== Criando as Páginas Web
Neste exercício, você criará duas páginas Web para exibir os dados. Você modificará o ``index.xhtml`` gerado pelo IDE para adicionar uma tabela que exiba os filmes do banco de dados. Em seguida, você criará ``browse.xhtml`` para exibir os detalhes de um filme ao clicar no link "Exibir" da tabela. Você criará também uma página modelo do JSF que será utilizada por ``index.xhtml`` e ``browse.xhtml`` .
Para saber mais sobre a utilização do JSF 2.0 e modelos do Facelets, consulte link:jsf20-intro.html[+Introdução ao JavaServer Faces 2.0+]
=== Criando ``template.xhtml``
Primeiro, você criará o modelo de Facelets ``template.xhtml`` do JSF utilizado na composição das páginas ``index.xhtml`` e ``browse.xhtml`` .
1. Clique com o botão direito do mouse no nó do projeto DVDStore na janela Projetos e selecione Novo > Outro.
2. Selecione Modelo de Facelets na categoria JavaServer Faces. Clique em Próximo.
3. Digite *template* para o Nome do Arquivo e selecione o primeiro estilo de layout CSS.
4. Clique em Finalizar.
Quando você clica em Finalizar, o arquivo ``template.xhtml`` é aberto no editor. O modelo contém o código default a seguir.
[source,html]
----
<h:body>
<div id="top" class="top">
<ui:insert name="top">Top</ui:insert>
</div>
<div id="content" class="center_content">
<ui:insert name="content">Content</ui:insert>
</div>
</h:body>
----
. Modifique o elemento ``<ui:insert>`` para alterar o nome gerado default para "corpo".
[source,html]
----
<div id="content" class="center_content">
<ui:insert name="*body*">Content</ui:insert>
</div>
----
. Salve as alterações.
O conteúdo do elemento ``<ui:define name="body">`` nos arquivos ``index.xhtml`` e ``browse.xhtml`` será inserido no local identificado com `` <ui:insert name="body">Content</ui:insert>`` no modelo.
=== Modificando ``index.xhtml``
Quando você criou a aplicação Web, o IDE gerou automaticamente a página ``index.xhtml`` . Neste exercício, você modifica a página para exibir uma lista de títulos de filmes. A página JSF chama os métodos no FilmController do Bean Gerenciado pelo JSF para recuperar a lista de filmes e exibir uma tabela com títulos e descrições dos filmes.
1. Expanda a pasta Páginas Web na janela Projetos e abra ``index.xhtml`` no editor.
O assistente para Novo Projeto gerou a seguinte página ``index.xhtml`` default.
[source,xml]
----
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Hello from Facelets
</h:body>
</html>
----
. Modifique a página para utilizar os elementos JSF ``<ui:composition>`` e ``<ui:define>`` e adicione um elemento ``<h:form>`` .
[source,xml]
----
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
*xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="./template.xhtml">
<ui:define name="body">
<h:form>
</h:form>
</ui:define>
</ui:composition>*
</html>
----
Quando você começa a digitar as tags, o IDE adiciona a declaração da biblioteca de tags ``xmlns:ui="http://java.sun.com/jsf/facelets"`` .
Os elementos ``<ui:composition>`` e ``<ui:define>`` são utilizados em combinação com o modelo de página que você criará. O elemento ``<ui:composition>`` faz referência à localização do modelo que será utilizado por essa página. O elemento ``<ui:define>`` faz referência à posição no modelo que o código incluído ocupará.
. Adicione os seguintes links de navegação que chamam os métodos ``previous`` e ``next`` no Bean gerenciado pelo JSF.
[source,xml]
----
<ui:define name="body">
<h:form>
*<h:commandLink action="#{filmController.previous}" value="Previous #{filmController.pageSize}" rendered="#{filmController.hasPreviousPage}"/> 
<h:commandLink action="#{filmController.next}" value="Next #{filmController.pageSize}" rendered="#{filmController.hasNextPage}"/> *
</h:form>
</ui:define>
----
. Adicione o seguinte elemento ``dataTable`` (em negrito) para gerar a tabela para exibir os itens recuperados.
[source,xml]
----
<h:form styleClass="jsfcrud_list_form">
<h:commandLink action="#{filmController.previous}" value="Previous #{filmController.pageSize}" rendered="#{filmController.hasPreviousPage}"/> 
<h:commandLink action="#{filmController.next}" value="Next #{filmController.pageSize}" rendered="#{filmController.hasNextPage}"/> 
*<h:dataTable value="#{filmController.filmTitles}" var="item" border="0" cellpadding="2" cellspacing="0" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="Title"/>
</f:facet>
<h:outputText value="#{item.title}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Description"/>
</f:facet>
<h:outputText value="#{item.description}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink action="#{filmController.prepareView}" value="View"/>
</h:column>
</h:dataTable>
<br/>*
</h:form>
----
. Salve as alterações.
A página de índice agora exibirá uma lista de títulos de filmes no banco de dados. Cada linha da tabela inclui um link "Exibir" que chama o método ``prepareView`` no bean gerenciado. O método ``prepareView`` retornará "browse" e abrirá o ``browse.xhtml`` .
*Observação.* Quando você digitar a tag ``<f:facet>`` , o IDE adicionará a declaração da biblioteca de tags ``xmlns:f="http://java.sun.com/jsf/core`` . *Confirme se a biblioteca de tags está declarada no arquivo.*
=== Criando ``browse.xhtml``
Agora você criará a página ``browse.xhtml`` para exibir os detalhes do filme selecionado. É possível utilizar o assistente Cliente de Modelo de Facelets para criar a página com base no modelo de Facelets do JSF ``template.xhtml`` que você criou.
1. Clique com o botão direito do mouse no nó do projeto DVDStore na janela Projetos e selecione Novo > Outro.
2. Selecione Cliente de Modelo de Facelets na categoria JavaServer Faces. Clique em Próximo.
image::images/hib-faceletsclient.png[title="Tipo de arquivo Cliente de Modelo de Facelets no assistente Novo Arquivo"]
. Digite *browse* para o Nome do Arquivo.
. Localize o Modelo da página clicando em Procurar para abrir a caixa de diálogo Procurar Arquivos.
. Expanda a pasta Páginas Web e selecione ``template.xhtml`` . Clique em Selecionar Arquivo.
image::images/hib-browsetemplate.png[title="Selecione o modelo na caixa de diálogo Procurar Arquivos"]
. Selecione *<ui:composition>* para a Tag Raiz Gerada. Clique em Finalizar.
Quando você clica em Finalizar, o arquivo ``browse.xhtml`` abrirá no editor com o código a seguir.
[source,xml]
----
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./template.xhtml">
<ui:define name="top">
top
</ui:define>
<ui:define name="body">
body
</ui:define>
</ui:composition>
----
É possível ver que o novo arquivo especifica o arquivo ``template.xhtml`` e que a tag ``<ui:define>`` possui a propriedade ``name="body"``
. Adicione o código a seguir (em negrito) entre as tags ``<ui:define>`` para criar o form e chamar os métodos no FilmController do Bean gerenciado para recuperar os dados e preencher o form.
[source,xml]
----
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./template.xhtml"
*xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"*>
<ui:define name="top">
top
</ui:define>
<ui:define name="body">
*
<h:form>
<h:panelGrid columns="2">
<h:outputText value="Title:"/>
<h:outputText value="#{filmController.selected.title}" title="Title"/>
<h:outputText value="Description"/>
<h:outputText value="#{filmController.selected.description}" title="Description"/>
<h:outputText value="Genre"/>
<h:outputText value="#{filmController.category}"/>
<h:outputText value="Cast"/>
<h:outputText value="#{filmController.actors}"/>
<h:outputText value="Film Length"/>
<h:outputText value="#{filmController.selected.length} min" title="Film Length"/>
<h:outputText value="Language"/>
<h:outputText value="#{filmController.language}" title="Film Length"/>
<h:outputText value="Release Year"/>
<h:outputText value="#{filmController.selected.releaseYear}" title="Release Year">
<f:convertDateTime pattern="MM/dd/yyyy" />
</h:outputText>
<h:outputText value="Rental Duration"/>
<h:outputText value="#{filmController.selected.rentalDuration}" title="Rental DUration"/>
<h:outputText value="Rental Rate"/>
<h:outputText value="#{filmController.selected.rentalRate}" title="Rental Rate"/>
<h:outputText value="Replacement Cost"/>
<h:outputText value="#{filmController.selected.replacementCost}" title="Replacement Cost"/>
<h:outputText value="Rating"/>
<h:outputText value="#{filmController.selected.rating}" title="Rating"/>
<h:outputText value="Special Features"/>
<h:outputText value="#{filmController.selected.specialFeatures}" title="Special Features"/>
<h:outputText value="Last Update"/>
<h:outputText value="#{filmController.selected.lastUpdate}" title="Last Update">
<f:convertDateTime pattern="MM/dd/yyyy HH:mm:ss" />
</h:outputText>
</h:panelGrid>
<br/>
<br/>
<h:commandLink action="#{filmController.prepareList}" value="View All List"/>
<br/>
</h:form>
*
</ui:define>
</ui:composition>
</html>
----
É possível ver que os arquivos ``browse.xhtml`` e ``index.xhtml`` utilizarão o mesmo modelo de página.
. Salve as alterações.
== Executando o Projeto
O conceito básico da aplicação agora está concluído. Agora você pode executar a aplicação para verificar se tudo está funcionando corretamente.
1. Clique em Executar Projeto Principal na barra de ferramentas principal ou clique com o botão direito do mouse no nó da aplicação DVDStore na janela Projetos e selecione Executar.
O IDE salva todos os arquivos alterados, constrói e implanta a aplicação no servidor. O IDE abre a janela do browser no URL ``http://localhost:8080/DVDStore/`` que exibe a lista de filmes.
image::images/hib-browser1.png[title="Tela do browser exibindo a lista de filme na página de índice"]
. No browser, clique em "Exibir" para carregar o ``browse.xhtml`` e exibir os detalhes do filme.
=== Fazendo Download do Projeto da Solução
Você pode fazer o download da solução para este projeto como um projeto das seguintes formas.
* Faça download link:https://netbeans.org/projects/samples/downloads/download/Samples/JavaEE/DVDStoreEE6.zip[+de um arquivo compactado zip do projeto finalizado+].
* Faça o check-out do código-fonte do projeto das Amostras do NetBeans ao executar as etapas a seguir:
1. Escolha Equipe > Subversion > Efetuar check-out no menu principal.
2. Na caixa de diálogo Efetuar Check-out, insira o Repositório URL a seguir:
``https://svn.netbeans.org/svn/samples~samples-source-code``
Clique em Próximo.
. Clique em Procurar para abrir a caixa de diálogo Procurar nas Pastas do Repositório:
. Expanda o nó raiz e selecione *samples/javaee/DVDStoreEE6*. Clique em OK.
. Especifique a Pasta Local dos códigos-fonte.
. Clique em Finalizar.
Quando você clica em Finalizar, o IDE inicializa a pasta local como um repositório Subversion e verifica os códigos-fonte do projeto.
. Clique em Abrir Projeto na caixa de diálogo exibida quando o check-out for concluído.
*Observações.* Para saber mais sobre a instalação do Subversion, consulte a seção link:../ide/subversion.html#settingUp[+Configurando o Subversion+] no link:../ide/subversion.html[+Guia do Subversion no NetBeans IDE+].
=== Solução de Problemas
A maioria dos problemas que ocorrem com a aplicação do tutorial são devidos a dificuldades de comunicação entre o GlassFish Server Open Source Edition e o servidor de banco de dados MySQL. Se sua aplicação não for exibida corretamente, ou se estiver recebendo um erro do servidor, você pode verificar a seção link:mysql-webapp.html#troubleshoot[+Solução de Problemas+] do tutorial link:mysql-webapp.html[+Criando uma Aplicação Web Simples Usando um Banco de Dados MySQL+] ou o tutorial link:../ide/mysql.html[+Estabelecendo Conexão a um Banco de Dados MySQL+].
Se fizer download e executar o projeto da solução, você verá o seguinte erro na janela de Saída se for a primeira vez que você implantou uma aplicação que usa o banco de dados My SQL.
[source,java]
----
SEVERE: JDBC Driver class not found: com.mysql.jdbc.Driver
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1509)
[...]
at java.lang.Thread.run(Thread.java:680)
SEVERE: Initial SessionFactory creation failed.org.hibernate.HibernateException: JDBC Driver class not found: com.mysql.jdbc.Driver
INFO: cleaning up connection pool: null
INFO: Domain Pinged: stable.glassfish.org
----
Em sua janela do browser você pode ver um ``java.lang.ExceptionInInitializerError`` e o seguinte rastreamento de pilha.
[source,java]
----
java.lang.ExceptionInInitializerError
at dvdrental.HibernateUtil.<clinit>(HibernateUtil.java:28)
...
Caused by: org.hibernate.HibernateException: JDBC Driver class not found: com.mysql.jdbc.Driver
...
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
...
----
A mensagem de saída declara que o driver JDBC do banco de dados MySQL não foi encontrado. O motivo mais provável é que você precisa adicionar o arquivo do driver JDBC de MySQL em sua instalação do servidor GlassFish. Para confirmar se o driver não foi encontrado, navegue até o diretório ``_GLASSFISH-INSTALL_/glassfish/domains/domain1/lib`` em seu sistema local (no qual _GLASSFISH-INSTALL_ é seu diretório de instalação GlassFish). Se o diretório ``domain1/lib`` não contiver o arquivo do driver JDBC (por exemplo, `mysql-connector-java-5.1.13-bin.jar`) você precisa copiar o driver JDBC para o diretório. O driver JDBC de MySQL não é adicionado à sua instalação do GlassFish quando você instala o servidor.
Você pode adicionar uma cópia do driver JDBC do MySQL para sua instalação do GlassFish executando as seguintes etapas.
1. Faça download do link:http://dev.mysql.com/downloads/connector/j/[+Conector MySQL/driver J JDBC+].
2. Extrai o driver e copie o arquivo do driver (por exemplo, `mysql-connector-java-5.1.13-bin.jar`) para o diretório ``domain1/lib`` de sua instalação do GlassFish.
Se preferir, quando usar o IDE para criar uma aplicação que usa o banco de dados MySQL, o IDE pode automaticamente copiar o driver JDBC de MySQL para o servidor GlassFish quando você implantar o projeto, se necessário. Para confirmar se o IDE copiará os drivers JDBC necessários, escolha Ferramentas > Servidores do menu principal para abrir o gerenciador de Servidores e confirmar que a opção Ativar Implantação do Driver JDBC é selecionada para seu servidor GlassFish.
Depois de criar e implantar uma aplicação web que usa o banco de dados MySQL, se você navegar para o diretório `domain1/lib` de sua instalação GlassFish local você verá que o diretório contém o arquivo do driver JDBC.
link:/about/contact_form.html?to=3&subject=Feedback:%20Using%20Hibernate%20in%20a%20Web%20Application[+Enviar Feedback neste Tutorial+]
== Consulte Também
* link:jsf20-support.html[+Suporte a JSF 2.x no NetBeans IDE+]
* link:jsf20-intro.html[+Introdução ao JavaServer Faces 2.x+]
* link:../../trails/java-ee.html[+Trilha de Aprendizado do Java EE e Java Web+]