Gerando uma Aplicação CRUD JavaServer Faces 2.x Usando um Banco de Dados

This tutorial needs a review. You can open a JIRA issue, or edit it in GitHub following these contribution guidelines.

Neste tutorial, você utilizará o NetBeans IDE para criar uma aplicação Web que interaja com um banco de dados de backend. A aplicação oferece a capacidade de exibir e modificar os dados contidos no banco de dados, conhecida como recurso CRUD (Create, Read, Update, Delete). A aplicação que você desenvolverá contará com as seguintes tecnologias.

  • JavaServer Faces (JSF) 2.x para páginas Web de frontend, manipulação de validação e gerenciamento do ciclo de solicitação-resposta.

  • Java Persistence API (JPA) 2.0 utilizando EclipseLink para gerar classes de entidade a partir do banco de dados e gerenciar transações. (EclipseLink é a implementação de referência para JPA e é o provedor de persistência default para o GlassFish Server.)

  • Enterprise JavaBeans (EJB) 3.1, que oferece EJBs sem estado que acessam as classes de entidade e contém a lógica de negócios da aplicação.

O IDE oferece dois assistentes que geram todos os códigos da aplicação. O primeiro é o assistente para Classes de Entidade do Banco de Dados que permite gerar as classes de entidade a partir do banco de dados fornecido. Após criar as classes de entidade, você utiliza o assistente de Páginas JSF de Classes de Entidade para criar EJBs e beans gerenciados pelo JSF para as classes de entidade, bem como um conjunto de páginas de Facelets para manipular as views dos dados da classe de entidade. A seção final do tutorial, Explorando a Aplicação, é opcional e oferece vários exercícios para ajudá-lo a entender melhor a aplicação e a se familiarizar mais com o IDE.

netbeans stamp 80 74 73
Figure 1. O conteúdo desta página se aplica ao NetBeans IDE 7.2, 7.3, 7.4 e 8.0

Para concluir este tutorial, você precisa dos seguintes recursos e softwares.

Software ou Recurso Versão Necessária

NetBeans IDE

Pacote Java EE 7.2, 7.3, 7.4, 8.0

JDK (Java Development Kit)

7 ou 8

GlassFish Server Open Source Edition

3.x, 4.x

mysql-consult.zip (MySQL) ou javadb-consult.zip (JavaDB)

n/d

Observações:

  • O pacote Java EE do NetBeans IDE também inclui o GlassFish Server, um servidor compatível com Java EE necessário para este tutorial.

  • Para o projeto de solução deste tutorial, faça o download de ConsultingAgencyJSF20.zip.

Criando o Banco de Dados

Este tutorial utiliza um banco de dados de agência de consultoria chamado consult. O banco de dados não é incluído quando você instala o IDE, portanto, é necessário criar primeiro o banco de dados para seguir este tutorial.

O banco de dados consult foi projetado para demonstrar o escopo do suporte do IDE para manipular uma variedade de estruturas de banco de dados. Portanto, o banco de dados não é um exemplo de melhores práticas ou design de banco de dados recomendado. Em vez disso, ele tenta incorporar muitas funcionalidades relevantes encontradas em um design de banco de dados. Por exemplo, o banco de dados consult contém todos os tipos de relacionamento possíveis, chaves primárias compostas e muitos tipos de dados diferentes. Consulte as tabelas abaixo para obter uma visão geral mais detalhada da estrutura do banco de dados.

Observações:

  • Este tutorial utiliza o servidor de banco de dados MySQL, mas também é possível concluí-lo utilizando o servidor do banco de dados JavaDB. Para criar o banco de dados no JavaDB, faça download e extraia o arquivo compactado javadb-consult.zip. O arquivo compactado contém scripts SQL para criar, eliminar e preencher o banco de dados de consult.

  • Para obter mais informações sobre a configuração do IDE para trabalhar com o MySQL, consulte o tutorial Estabelecendo Conexão com um Banco de Dados MySQL.

  • Para obter mais informações sobre como configurar o IDE para trabalhar com JavaDB, consulte o tutorial Trabalhando com o Banco de Dados Java DB (Derby).

Combinação MySQL com GlassFish:

Se você estiver usando o MySQL, e estiver usando o GlassFish v3 ou Open Source Edition 3.0.1, será preciso garantir que seu banco de dados esteja protegido por senha. (Para obter mais informações, consulte GlassFish Edição 12221.) Se você estiver utilizando a conta MySQL root sem senha, você poderá definir a senha usando um prompt de linha de comandos.

Por exemplo, para definir a senha para nbuser, digite os comandos a seguir no prompt de linha de comandos.

shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('_nbuser_') WHERE User = 'root';
mysql> FLUSH PRIVILEGES;

Se você receber um erro ‘mysql: command not found’, será porque o comando mysql não foi adicionado à sua variável de ambiente PATH. É possível chamar o comando inserindo o caminho completo para o diretório bin da instalação do MySQL. Por exemplo, se o comando mysql estiver localizado no seu computador em /usr/local/mysql/bin, digite o seguinte:

shell> /usr/local/mysql/bin/mysql -u root

Para obter mais informações, consulte o Manual de Referência oficial do MySQL:

Execute as etapas a seguir para criar um banco de dados e conecte-o a partir do IDE.

  1. Faça download de mysql-consult.zip e o extraia o arquivo compactado no seu sistema local. Quando você extrair o arquivo compactado, você verá os scripts SQL para criação e preenchimento do banco de dados. O arquivo compactado também tem scripts para eliminação de tabelas.

  2. Na janela Serviços, expanda o nó Bancos de Dados, clique com o botão direito do mouse no nó MySQL e selecione Iniciar Servidor.

  3. Clique com o botão direito do mouse no nó Servidor MySQL e escolha Criar Banco de Dados.

  4. Digite consult como o Nome do Banco de Dados na caixa de diálogo Criar Banco de Dados MySQL. Clique em OK. Um novo nó aparecerá sob o nó Bancos de Dados (jdbc:mysql://localhost:3306/consult [raiz no esquema Default]).

  5. Clique com o botão direito do mouse no novo nó e selecione Conectar.

  6. Selecione Arquivo > Abrir Arquivo, no menu principal e vá até o arquivo extraído mysql_create_consult.sql. Clique em Abrir. O arquivo abre automaticamente no editor SQL.

run sql script
Figure 2. Abrir arquivos SQL no editor do IDE
  1. Certifique-se de que o banco de dados consult esteja selecionado na lista drop-down Conexão da barra de ferramentas do editor SQL. Em seguida, clique no botão ( run sql btn ) Executar SQL.

Quando você clica em Executar SQL, a saída a seguir é exibida na janela de Saída.

run sql output
Figure 3. A janela de Saída oferece informações sobre a execução SQL

Examinando a Estrutura do Banco de Dados

Para confirmar se as tabelas foram criadas corretamente, expanda o nó Tabelas sob o nó da conexão do banco de dados. Você pode expandir um nó da tabela para ver suas colunas, índices e chaves estrangeiras. É possível clicar com o botão direito do mouse em uma coluna e selecionar Propriedades para exibir informações adicionais sobre a coluna.

services window tables
Figure 4. A janela Serviços exibe conexões de bancos de dados, tabelas, colunas de tabelas, índices e chaves estrangeiras

Observação: Se você não vir nenhuma tabela sob o nó Tabelas, clique com o botão direito do mouse no nó Tabelas e selecione Atualizar.

Ao observar a estrutura do banco de dados consult, você pode ver que o banco de dados contém tabelas que possuem uma variedade de relacionamentos e vários tipos de campo. Quando você cria classes de entidade de um banco de dados, o IDE gera automaticamente o código apropriado para os vários tipos de campo.

diagram consult
Figure 5. Diagrama de relacionamento com entidades do banco de dados consult

A tabela a seguir descreve as tabelas encontradas no banco de dados consult.

Tabela de Banco de Dados Descrição Funcionalidades de Design

CLIENT

Um cliente da agência de consultoria

Chave primária composta, não gerada (cujos campos não constituem uma chave estrangeira)

CONSULTANT

Um funcionário da agência de consultoria que os clientes podem contratar

Inclui um campo de retomada do tipo LONG VARCHAR

CONSULTANT_STATUS

O status de um consultor na agência de consultoria (por exemplo, Ativo e Inativo são status possíveis)

Chave primária não gerada do tipo CHAR

RECRUITER

Um funcionário da agência de consultoria responsável por conectar clientes e consultores

 

PROJECT

Um projeto cuja equipe é formada pelos consultores da agência de consultoria

Chave primária composta, não gerada que inclui dois campos que constituem uma chave estrangeira para a tabela CLIENT

BILLABLE

Um conjunto de horas trabalhadas por um consultor em um projeto, o qual a agência de consultoria cobra do cliente relevante

Inclui um campo de artefato do tipo CLOB

ADDRESS

O endereço de cobrança de um cliente

 

PROJECT_CONSULTANT

Tabela com junção indicando a quais projetos os consultores estão designados no momento

Faz referência cruzada entre PROJECT e CONSULTANT, a primeira possui uma chave primária composta

O banco de dados consult inclui uma variedade de relacionamentos. Quando você cria classes de entidade de um banco de dados, o IDE gera automaticamente as propriedades do tipo Java apropriado com base no tipo SQL das colunas. A tabela a seguir descreve os relacionamentos de entidade do banco de dados consult. (os relacionamentos inversos não são mostrados.)

Entidade Entidade Relacionada Informações sobre Relacionamento Descrição

CLIENT

RECRUITER

pode ser nulo, um para um com edição manual; pode ser nulo, um para muitos, caso não seja editado

CLIENT possui muitos RECRUITERs e RECRUITER não possui nenhum ou um CLIENT (se não for manualmente editado)

CLIENT

ADDRESS

não pode ser nulo, um para um

CLIENT possui um ADDRESS e ADDRESS não possui nenhum ou um CLIENT

CLIENT

PROJECT

não pode ser nulo, um para muitos; em uma entidade de Projeto, o valor do campo do cliente faz parte da chave primária do Projeto

CLIENT tem muitos PROJECTS e PROJECT tem um CLIENT

CONSULTANT

PROJECT

muitos para muitos

CONSULTANT tem muitos PROJECTs e PROJECT tem muitos CONSULTANTs

CONSULTANT

BILLABLE

não pode ser nulo, um para muitos

CONSULTANT possui muitos BILLABLEs e BILLABLE possui um CONSULTANT

CONSULTANT_STATUS

CONSULTANT

não pode ser nulo, um para muitos

CONSULTANT_STATUS possui muitos CONSULTANTs e CONSULTANT possui um CONSULTANT_STATUS

CONSULTANT

RECRUITER

pode ser nulo, um para muitos

CONSULTANT não possui nenhum ou um RECRUITER e RECRUITER possui muitos CONSULTANTs

BILLABLE

PROJECT

não pode ser nulo, um para muitos

BILLABLE possui um PROJECT e PROJECT possui muitos BILLABLES

Agora que o banco de dados está criado, você pode criar a aplicação Web e utilizar o assistente de Classes de Entidade do Banco de Dados para gerar bancos de dados com base nas tabelas do banco de dados.

Criando o Projeto de Aplicação Web

Neste exercício, você criará um projeto Web e adicionará o framework JavaServer Faces ao projeto. Ao criar o projeto, você irá selecionar JavaServer Faces no painel Frameworks do assistente de Novo Projeto.

  1. Escolha Arquivo > Novo Projeto (Ctrl-Shift-N; &#8984-Shift-N no Mac) no menu principal.

  2. Na categoria Java Web, selecione Aplicação Web. Clique em Próximo.

  3. Digite `ConsultingAgency ` para o nome do projeto e defina a localização do projeto. Clique em Próximo.

  4. 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.

  5. No painel Frameworks, selecione a opção JavaServer Faces. Clique em Finalizar.

Quando você clicar em Finalizar, o IDE irá gerar o projeto de aplicação Web e abrir index.xhtml no editor.

Gerando as Classes de Entidade do Banco de Dados

Depois de se conectar a um banco de dados do IDE, você pode utilizar o assistente de Classes de Entidade do Banco de Dados para gerar rapidamente classes de entidade com base nas tabelas do banco de dados. O IDE pode gerar classes de entidade para cada tabela selecionada, e também pode gerar classes de entidade necessárias para tabelas relacionadas.

  1. Na janela Projetos, clique com o botão direito do mouse no nó do projeto ` ConsultingAgency` e selecione Novo > Classes de Entidade do Banco de Dados. (Se esta opção não estiver na lista, escolha Outros. Em seguida, no assistente de Arquivo, selecione a categoria Persistência e, depois, Classes de Entidade do Banco de Dados.)

  2. Selecione Nova Fonte de Dados na lista drop-down Fonte de Dados para abrir a caixa de diálogo Criar Fonte de Dados.

  3. Digite jdbc/consult como o Nome da JNDI e selecione a conexão jdbc:mysql://localhost:3306/consult como a Conexão do Banco de Dados.

create datasource
Figure 6. Especificar um nome e uma conexão de banco de dados JNDI para criar uma fonte de dados
  1. Clique em OK para fechar a caixa de diálogo e retornar ao assistente. As tabelas no banco de dados consult serão exibidas na lista de conteúdo Tabelas Disponíveis.

  2. Clique no botão Adicionar Tudo para selecionar todas as tabelas contidas no banco de dados. Clique em Próximo.

new entities wizard
  1. Digite jpa.entities como o nome do Pacote.

  2. Verifique se as caixas de seleção para gerar as consultas nomeadas e criar uma unidade persistente estão marcadas. Clique em Finalizar.

Quando você clicar em Finalizar, o IDE gerará as classes de entidade no pacote jpa.entities do projeto.

Quando você utiliza o assistente para criar classes de entidade de um banco de dados, o IDE examina os relacionamentos entre as tabelas do banco de dados. Na janela Projetos, se você expandir o nó do pacote jpa.entities, você verá que o IDE gerou uma classe de entidade para cada tabela, exceto para a tabela PROJECT_CONSULTANT. O IDE não criou uma classe de entidade para PROJECT_CONSULTANT porque a tabela é uma tabela com junção.

projects window entities
Figure 7. Tela da janela Projetos mostrando as classes de entidades geradas

O IDE também gerou duas classes adicionais para as tabelas com chaves primárias compostas: CLIENT e PROJECT. As classes de chave primária dessas tabelas (ClientPK.java e ProjectPK.java) têm as letras PK acrescentadas ao nome.

Se você observar o código gerado para as classes de entidade, você verá que o assistente adicionou anotações @GeneratedValue aos campos ID gerados automaticamente e anotações @Basic(optional = "false") a alguns dos campos das classes de entidade. Com base nas anotações @Basic(optional = "false"), o assistente de Páginas JSF de Classes de Entidade pode gerar o código que inclui verificações para evitar violações de coluna que não podem ser nulas para esses campos.

Gerando Páginas JSF de Classes de Entidade

Agora que as classes de entidade estão criadas, você pode criar a interface Web para exibir e modificar os dados. Você utilizará o assistente de Páginas JSF de Classes de Entidade para gerar páginas JavaServer Faces. O código gerado pelo assistente baseia-se nas anotações de persistência contidas nas classes de entidade.

Para cada classe de entidade o assistente gera os seguintes arquivos:

  • um bean de sessão sem estado que estende AbstractFacade.java

  • um bean gerenciado com escopo de sessão JSF

  • um diretório contendo quatro arquivos de Facelets para os recursos CRUD (Create.xhtml, Edit.xhtml, List.xhtml e View.xhtml)

O assistente também gera os seguintes arquivos.

  • a classe AbstractFacade.java que contém a lógica de negócio para criação, recuperação, modificação e remoção das instâncias da entidade

  • classes de utilitário utilizadas pelos beans gerenciados pelo JSF (JsfUtil, PaginationHelper)

  • um conjunto de propriedades para mensagens localizadas e uma entrada correspondente no arquivo de configuração Faces do projeto (será criado um arquivo faces-config.xml, caso já não exista um).

  • arquivos web auxiliares, incluindo uma folha de estilo default para componentes renderizados e um arquivo de modelo de Facelets

Para gerar as páginas JSF:

  1. Na janela Projetos, clique com o botão direito do mouse no nó do projeto e selecione Novo > Páginas JSF de Classes de Entidade para abrir o assistente. (Se esta opção não estiver na lista, escolha Outros. Em seguida, no assistente de Arquivo, selecione a categoria JavaServer Faces e, depois, Páginas JSF de Classes de Entidade.)

A caixa Classes de Entidade Disponíveis lista as sete classes de entidade contidas no projeto. A caixa não lista as classes incorporadas (ClientPK.java e ProjectPK.java).

  1. Clique em Adicionar Tudo para mover todas as classes para a caixa Classes de Entidade Selecionadas.

newjsf wizard
Figure 8. O assistente de Novas Páginas JSF de Classes de Entidade exibe todas as classes de entidade contidas no projeto

Clique em Próximo.

  1. Na etapa 3 do assistente, Gerar Classes e Páginas JSF, digite jpa.session no Pacote de Bean de Sessão JPA.

  2. Digite jsf para o Pacote de Classes JSF.

  3. Digite ‘/resources/Bundle’ no campo Nome do Pacote de Localização. Isso gerará um pacote com o nome resources no qual o arquivo Bundle.properties residirá. (Se deixá-lo em branco, o conjunto de propriedades será criado no pacote default do projeto.)

newjsf wizard2
Figure 9. Especificar pacote e nomes de pastas para os arquivos gerados

Para que o IDE se ajuste melhor às convenções do projeto, você pode personalizar os arquivos gerados pelo assistente. Clique no link Personalizar Modelo para modificar os modelos de arquivo utilizados pelo assistente.

customize template
Figure 10. Personalizar modelos de arquivos gerados pelo assistente

Em geral, você pode acessar e fazer alterações em todos os modelos mantidos pelo IDE utilizando o Gerenciador de Modelos (Ferramentas > Modelos).

  1. Clique em Finalizar. O IDE gera os beans de sessão sem estado no pacote jpa.session, e o escopo de sessão e beans gerenciados com JSF no pacote jsf. Cada bean de sessão sem estado manipula as operações da classe de entidade correspondente, incluindo a criação, edição e destruição de instâncias da classe de entidade por meio da API de Persistência Java. Cada Bean gerenciado pelo JSF implementa a interface javax.faces.convert.Converter e realiza as tarefas de conversão das instâncias da classe de entidade correspondente para objetos String e vice-versa.

Se você expandir o nó Páginas Web, você poderá ver que o IDE gerou uma pasta para cada uma das classes de entidade. Cada pasta contém os arquivos Create.xhtml, Edit.xhtml, List.xhtml e View.xhtml. O IDE também modificou o arquivo index.xhtml inserindo links em cada uma das páginas List.xhtml.

projects jsfpages
Figure 11. Páginas de Facelets para cada classe de entidade são geradas pelo assistente

Cada Bean gerenciado pelo JSF é específico dos quatro arquivos de Facelets correspondentes e inclui o código que chama os métodos no Bean de sessão apropriado.

Expanda o nó da pasta resources para localizar a folha de estilo jsfcrud.css default gerada pelo assistente. Se você abrir a página de boas-vindas da aplicação (index.xhtml) ou o arquivo de modelo de Facelets (template.xhtml) no editor, verá que eles contêm uma referência à folha de estilo.

<h:outputStylesheet name="css/jsfcrud.css"/>

O arquivo de modelo de Facelets é utilizado por cada um dos quatro arquivos de Facelets para cada classe de entidade.

Se você expandir o nó Pacotes de Código-Fonte, você verá os Beans de sessão, os Beans gerenciados pelo JSF, as classes de utilitário e o conjunto de propriedades gerados pelo assistente.

projects generated classes70
Figure 12. Tela do diretório de Pacotes de Código-Fonte na janela Projetos mostrando as classes geradas pelo assistente

O assistente também gerou o arquivo de Configuração do Faces (faces-config.xml) a fim de registrar a localização do conjunto de propriedades. Se expandir o nó Arquivos de Configuração e abrir faces-config.xml no editor XML, você verá que a entrada a seguir está incluída.

<application>
    <resource-bundle>
        <base-name>/resources/Bundle</base-name>
        <var>bundle</var>
    </resource-bundle>
</application>

Além disso, se expandir o novo pacote resources, você encontrará o arquivo Bundle.properties que contém mensagens no idioma default do cliente. As mensagens são obtidas das propriedades da classe de entidade.

Para adicionar um novo conjunto de propriedades, clique com o botão direito do mouse no arquivo Bundle.properties e selecione Personalizar. A caixa de diálogo Personalizador permite adicionar novas configurações regionais à aplicação.

Explorando a Aplicação

Agora que seu projeto contém classes de entidade, Beans de sessão EJB para controlar as classes de entidade e um frontend desenvolvido para JSF para exibir e modificar bancos de dados, tente executar o projeto para ver os resultados.

A seguir, encontra-se uma série opcional de exercícios rápidos que ajudará você a se familiarizar com a aplicação, bem como com os recursos e as funcionalidades que o IDE oferece.

Examinando o Projeto Concluído

  1. Para executar o projeto, clique com o botão direito do mouse no nó do projeto, na janela Projetos, e selecione Executar ou clique no botão ( run project btn ) Executar Projeto na barra de ferramentas principal.

Quando a página de boas-vindas da aplicação é exibida, aparece uma lista de links que permite exibir as entradas contidas em cada uma das tabelas do banco de dados.

welcome page links
Figure 13. Links para exibição do conteúdo do banco de dados para cada tabela

Os links foram adicionados à página de boas-vindas (index.xhtml) ao concluir o assistente de Páginas JSF de Classes de Entidade. Esses links são fornecidos como pontos de entrada nas páginas de Facelets que oferecem a funcionalidade CRUD no banco de dados da Agência de Consultoria.

<h:body>
    Hello from Facelets
    <h:form>
        <h:commandLink action="/address/List" value="Show All Address Items"/>
    </h:form>
    <h:form>
        <h:commandLink action="/billable/List" value="Show All Billable Items"/>
    </h:form>
    <h:form>
        <h:commandLink action="/client/List" value="Show All Client Items"/>
    </h:form>
    <h:form>
        <h:commandLink action="/consultant/List" value="Show All Consultant Items"/>
    </h:form>
    <h:form>
        <h:commandLink action="/consultantStatus/List" value="Show All ConsultantStatus Items"/>
    </h:form>
    <h:form>
        <h:commandLink action="/project/List" value="Show All Project Items"/>
    </h:form>
    <h:form>
        <h:commandLink action="/recruiter/List" value="Show All Recruiter Items"/>
    </h:form>
</h:body>
  1. Clique no link ‘Mostrar todos os Itens do Consultor’. Ao observar o código acima, você pode ver que a página de destino é /consultant/List.xhtml. (No JSF 2.x, a extensão do arquivo é deduzida devido à navegação implícita.)

empty consultants list
Figure 14. A tabela Consultores está vazia no momento

Atualmente, o banco de dados não contém dados de amostra. É possível adicionar dados manualmente clicando no link ‘Criar Novo Consultor’ e utilizando o Web form fornecido. A página /consultant/Create.xhtml é carregada para que seja exibida. Você também pode executar um script SQL no IDE para preencher as tabelas com os dados de amostra. As subseções a seguir exploram ambas as opções.

Você pode clicar no link do índice para voltar à lista de links da página de boas-vindas. Os links oferecem uma view dos dados contidos em cada tabela do banco de dados e carrega o arquivo List.xhtml de cada pasta de entidade para que seja exibido. Conforme será demonstrado posteriormente, após adicionar os dados às tabelas, outros links serão exibidos em cada entrada permitindo que você exiba (View.xhtml), edite (Edit.xhmtl) e destrua os dados de um único registro da tabela.

Observação. Se a implantação da aplicação falhar, consulte a seção de solução de problemas a seguir. (Consulte também a seção de solução de problemas de Criando uma Aplicação Web Simples Usando um Banco de Dados MySQL.)

Preenchendo o Banco de Dados com um Script SQL

Execute o script fornecido, que gera dados de amostra para as tabelas do banco de dados. O script (mysql_insert_data_consult.sql) está incluído no arquivo ZIP Consultando o Banco de Dados da Agência que pode ser obtido por download da tabela de software exigido.

Dependendo do servidor de banco de dados com que estiver trabalhando (MySQL ou JavaDB), você poderá executar o script fornecido, que irá gerar dados de amostra para as tabelas de banco de dados. Para o MySQL, esse é o script mysql_insert_data_consult.sql. Para o JavaDB, esse é o script javadb_insert_data_consult.sql. Ambos os scripts são incluídos nos respectivos arquivos compactados, que podem ser obtidos por download na tabela de software exigido.

  1. Selecione Arquivo > Abrir Arquivo no menu principal e, em seguida, vá até o local do script no seu computador. Clique em Abrir. O arquivo é aberto automaticamente no editor SQL do IDE.

  2. Certifique-se de que o banco de dados consult esteja selecionado na lista drop-down Conexão da barra de ferramentas do editor SQL.

run sql insert
Figure 15. Abrir o script no editor SQL do IDE

Clique com o botão direito do mouse no editor e selecione Executar Instrução ou clique no botão ( run sql btn ) Executar SQL. É possível ver o resultado da execução do script na janela de Saída.

  1. Reinicie o GlassFish Server. Essa é uma etapa necessária para ativar o servidor e recarregar e armazenar no cache os novos dados contidos no banco de dados consult. Para isso, clique na guia do GlassFish Server na janela de Saída (A guia do GlassFish Server exibirá o log do servidor.), em seguida, clique no botão ( glassfish restart ) Reiniciar Servidor na margem esquerda. O servidor para e, em seguida, reinicia.

  2. Execute o projeto novamente e clique no link ‘Mostrar Todos os Itens do Consultor’. Você verá que a lista não está mais vazia.

consultants list small

Suporte ao Banco de Dados NetBeans

É possível utilizar o visualizador de tabelas do banco de dados do IDE para exibir e modificar os dados da tabela mantidos diretamente no banco de dados. Por exemplo, clique com o botão direito do mouse na tabela consultant na janela Serviços e selecione Exibir Dados.

view data
Figure 16. Selecione Exibir Dados no menu contextual das tabelas de banco de dados

A consulta SQL utilizada para executar a ação é exibida na parte superior do editor e uma exibição gráfica da tabela é exibida abaixo.

view data table small

Clique duas vezes nas células da tabela para efetuar modificações diretamente nos dados. Clique no ícone ( commit records icon ) Confirmar Registros para confirmar as alterações feitas no banco de dados.

A view gráfica oferece mais funcionalidade. Consulte Suporte ao Banco de Dados no NetBeans IDE para obter mais informações.

Explorando o Suporte do Editor em Páginas de Facelets

  1. Abra a página /consultant/List.xhtml no editor. A linha 8 indica que a página depende do arquivo de Facelets template.xhtml para que ser renderizada.

<ui:composition template="/template.xhtml">

Para exibir os números das linhas, clique com o botão direito do mouse na margem esquerda do editor e selecione Mostrar Números de Linhas.

  1. Utilize a caixa de diálogo Ir para Arquivo do IDE para abrir o arquivo template.xhtml. Pressione Alt-Shift-O (Ctrl-Shift-O no Mac) e, em seguida, digite modelo.

go to file
Figure 17. Utilizar a caixa de diálogo Ir para Arquivo para abrir rapidamente arquivos do projeto

Clique em OK (ou pressione Enter).

  1. O modelo aplica as tags <ui:insert> para inserir o conteúdo de outros arquivos no título e corpo. Coloque o cursor na tag <ui:insert> e pressione Ctrl-Espaço para chamar uma janela pop-up de documentação.

doc popup
Figure 18. Pressione Ctrl-Espaço para chamar um pop-up de documentação nas tags de Facelets

É possível pressionar Ctrl-Espaço nas tags JSF e seus atributos para chamar o pop-up da documentação. A documentação exibida é obtida das descrições fornecidas na Documentação da Biblioteca de Tags JSF Oficial.

  1. Volte para o arquivo List.xhtml (pressione Ctrl-Tab). As tags <ui:define> são utilizadas para definir o conteúdo que será aplicado ao título e ao corpo do modelo. Esse padrão é utilizado nos quatro arquivos de Facelets (Create.xhtml, Edit.xhtml, List.xhtml e View.xhtml) gerados para cada classe de entidade.

  2. Coloque seu cursor em qualquer uma das expressões EL utilizadas nas mensagens localizadas contidas no arquivo Bundle.properties. Pressione Ctrl-Espaço para exibir a mensagem localizada.

localized messages small

Na imagem acima, você pode ver que a expressão EL é determinada como ‘List’, que é aplicada ao título do modelo e pode ser verificada na página renderizada no browser.

  1. Navegue até a parte inferior do arquivo e localize o código do link Criar novo consultor (Linha 92). Trata-se do seguinte:

<h:commandLink action="#{consultantController.prepareCreate}" value="#{bundle.ListConsultantCreateLink}"/>
  1. Pressione Ctrl-Espaço no atributo action do commandLink para chamar a janela pop-up da documentação.

O atributo ação indica o método que manipula a solicitação quando o link é clicado no browser. A documentação a seguir será fornecida:

MethodExpression, que representa a ação da aplicação a qual será chamada quando este componente for ativado pelo usuário. A expressão deve ser interpretada como um método público que não toma nenhum parâmetro e retorna um Object (o toString() do qual é chamado para gerar o resultado lógico) que será passado para o NavigationHandler desta aplicação. Em outras palavras, o valor de action se refere normalmente a um método em um bean gerenciado pelo JSF que é avaliado como uma String. Então, a string é utilizada pelo NavigationHandler do JSF para encaminhar a solicitação para a view apropriada. É possível verificar isso nas etapas a seguir.

  1. Coloque o cursor no consultantController e pressione Ctrl-Espaço. A funcionalidade autocompletar código do editor indica que consultantController é um Bean gerenciado pelo JSF.

code completion managed bean
Figure 19. A funcionalidade autocompletar código é fornecida para Beans gerenciados pelo JSF
  1. Mova o cursor para prepareCreate e pressione Ctrl-Espaço. A funcionalidade autocompletar código lista os métodos contidos no Bean gerenciado ConsultantController.

code completion properties
Figure 20. A funcionalidade autocompletar código é fornecida para métodos de classe
  1. Pressione Ctrl (&#8984 no Mac) e, em seguida mova o mouse sobre prepareCreate. É formado um link, que permite ir diretamente para o método prepareCreate() no Bean gerenciado ConsultantController.

editor navigation
Figure 21. Utilizar a navegação do editor para ir rapidamente até o código-fonte
  1. Clique no link e exiba o método prepareCreate() (exibido a seguir).

public String prepareCreate() {
    current = new Consultant();
    selectedItemIndex = -1;
    return "Create";
}

O método retornará Create. O NavigationHandler coleta informações em segundo plano e aplica a string Create ao caminho que indica a view enviada em resposta à solicitação: /consultant/Create.xhtml. (No JSF 2.x, a extensão do arquivo é deduzida devido à navegação implícita.)

Explorando a Integridade do Banco de Dados com Validação de Campo

  1. Na página Lista de Consultores do browser, clique no link ‘Criar Novo Consultor’. Conforme demonstrado na subseção anterior, isso carrega a página /consultant/Create.xhtml para que seja renderizada.

  2. Informe os detalhes a seguir no form: Temporariamente, deixe os campos RecruiterId e StatusId em branco.

Campo Valor

ConsultantId

2

Email

jack.smart@jsfcrudconsultants.com

Password

jack.smart

HourlyRate

75

BillableHourlyRate

110

HireDate

22/07/2008

Retomar

Sou um ótimo consultor. Contrate-me - Você não vai se arrepender!

RecruiterId

---

StatusId

---

  1. Clique em Salvar. Quando você fizer isso, um erro de validação será sinalizado no campo StatusId.

create new consultant
Figure 22. Informar os dados de amostra no form

Por que aconteceu isso? Examine novamente o diagrama de relacionamento com entidades do banco de dados da Agência de Consultoria. Conforme apresentado na tabela de relacionamentos acima, as tabelas CONSULTANT e CONSULTANT_STATUS compartilham um relacionamento que não pode ser nulo, um para muitos. Portanto, cada entrada da tabela CONSULTANT deve conter uma referência a uma entrada na tabela CONSULTANT_STATUS. Isso é indicado pela chave estrangeira consultant_fk_consultant_status que vincula as duas tabelas.

É possível exibir as chaves estrangeiras contidas nas tabelas expandindo o nó Chaves Estrangeiras da tabela na janela Serviços (Ctrl-5; &#8984-5 no Mac).

consultant fk
Figure 23. Examinar os atributos da chave estrangeira na janela Serviços
  1. Para solucionar o erro de validação, selecione entity.ConsultantStatus[statusId=A] na lista drop-down StatusId.

*Observação: *Você pode deixar o campo RecruiterId em branco. Conforme indicado no diagrama de relacionamento com as entidades do banco de dados, há um relacionamento que pode ser nulo, um para muitos entre as tabelas CONSULTANT e RECRUITER, indicando que as entradas em CONSULTANT não precisam estar associadas a uma entrada de RECRUITER.

  1. Clique em Salvar. Será exibida uma mensagem indicando que a entrada do consultor foi salva com êxito. Se você clicar em Exibir Todos os Itens do Consultor, você verá a nova entrada listada na tabela.

Em geral, as páginas de Facelets geradas produzem erros para entradas do usuário que introduz:

  • campos vazios em células de tabela que não podem ser nulas.

  • modificações em dados que não podem ser alterados (por exemplo, chaves primárias).

  • inserção de dados que não são do tipo correto.

  • modificações em dados quando uma view do usuário não estiver mais sincronizada com o banco de dados.

Editando as Classes de Entidade

Na subseção anterior, você viu como a lista drop-down StatusId forneceu a opção mais complexa entity.ConsultantStatus[statusId=A]. Você já deve ter notado que o texto exibido em cada item desta lista drop-down é a representação de uma string de cada entidade ConsultantStatus encontrada (por exemplo, o método toString() da classe de entidade é chamado).

Essa subseção demonstra como você pode utilizar a funcionalidade autocompletar código, a documentação e o suporte à navegação do editor para chegar a essa conclusão. Também oferece uma mensagem mais amigável para a lista drop-down.

  1. Abra o arquivo /consultant/Create.xhtml no editor. Trata-se do form Criar Novo Consultor que você acaba de exibir no browser. Role para baixo até o código da lista drop-down StatusId (ilustrado em negrito abaixo).

    <h:outputLabel value="#{bundle.CreateConsultantLabel_resume}" for="resume" />
    <h:inputTextarea rows="4" cols="30" id="resume" value="#{consultantController.selected.resume}" title="#{bundle.CreateConsultantTitle_resume}" />
    *<h:outputLabel value="#{bundle.CreateConsultantLabel_statusId}" for="statusId" />
    <h:selectOneMenu id="statusId" value="#{consultantController.selected.statusId}" title="#{bundle.CreateConsultantTitle_statusId}" required="true" requiredMessage="#{bundle.CreateConsultantRequiredMessage_statusId}">
        <f:selectItems value="#{consultantStatusController.itemsAvailableSelectOne}"/>
    </h:selectOneMenu>*
    <h:outputLabel value="#{bundle.CreateConsultantLabel_recruiterId}" for="recruiterId" />
    <h:selectOneMenu id="recruiterId" value="#{consultantController.selected.recruiterId}" title="#{bundle.CreateConsultantTitle_recruiterId}" >
        <f:selectItems value="#{recruiterController.itemsAvailableSelectOne}"/>
    </h:selectOneMenu>
</h:panelGrid>
  1. Examine o value aplicado à tag <f:selectItems>. O atributo value determina o texto exibido para cada item na lista drop-down.

Pressione Ctrl-Espaço em itemsAvailableSelectOne. A funcionalidade autocompletar código do editor indica que o método getItemsAvailableSelectOne() do ConsultantStatusController retorna um array de objetos SelectItem.

code completion returned object
Figure 24. A funcionalidade autocompletar código exibe as classes retornadas para os métodos
  1. Pressione Ctrl (&#8984 no Mac) e, em seguida, mova o mouse sobre itemsAvailableSelectOne. É formado um link que permite ir diretamente para o método getItemsAvailableSelectOne() no código-fonte da entidade ConsultantStatus. Clique neste link.

  2. Coloque o cursor sobre o valor de retorno SelectItem[] na assinatura do método e pressione Ctrl-Espaço para chamar a janela pop-up da documentação.

documentation select item
Figure 25. Pressione Ctrl-Espaço para chamar o suporte à documentação

Clique no ícone ( web browser icon ) Web browser na janela da documentação para abrir o Javadoc em um Web browser externo.

Como você pode ver, a classe SelectItem pertence ao framework JSF. O componente UISelectOne, conforme mencionado na documentação, é representado pela tag <h:selectOneMenu> da marcação que você examinou na Etapa 1 acima.

  1. Pressione Ctrl (&#8984 no Mac) e, em seguida, mova o mouse sobre findAll(). Uma janela pop-up será exibida com a assinatura do método.

method signature
Figure 26. Exibir pop-ups das assinaturas do método no editor

É possível observar que aqui o ejbFacade.findAll() retorna uma Lista de objetos ConsultantStatus.

  1. Vá para JsfUtil.getSelectItems. Coloque o mouse sobre getSelectItems e pressione Ctrl (&#8984 no Mac), a seguir, clique no link exibido.

*Observação: *Lembre-se de que JsfUtil é uma das classes de utilitário geradas ao concluir o assistente de Páginas JSF de Classes de Entidade.

O método cria o loop por meio da lista de entidades (por exemplo, a List de objetos ConsultantStatus), criando um SelectItem para cada entidade. Conforme indicado abaixo em negrito, cada SelectItem é criado utilizando o objeto da entidade e um label para o objeto.

public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {
    int size = selectOne ? entities.size() + 1 : entities.size();
    SelectItem[] items = new SelectItem[size];
    int i = 0;
    if (selectOne) {
        items[0] = new SelectItem("", "---");
        i++;
    }
    *for (Object x : entities) {
        items[i++] = new SelectItem(x, x.toString());
    }*
    return items;
}

O label é criado utilizando o método toString() da entidade e corresponde à representação do objeto quando renderizado na resposta. (Consulte a definição do Javadoc para o construtor SelectItem(java.lang.Object value, java.lang.String label).)

Agora que você verificou que o método toString() da entidade é o método renderizado no browser ao exibir os itens em uma lista drop-down, modifique o método toString() do ConsultantStatus.

  1. Abra a classe de entidade ConsultantStatus no editor. Modifique o método toString para retornar statusId e description. Trata-se das propriedades da entidade que correspondem às duas colunas da tabela CONSULTANT_STATUS.

public String toString() {
    return *statusId + ", " + description;*
}
  1. Execute o projeto novamente. Quando o browser exibir a página de boas-vindas, clique no link Mostrar Todos os Itens do Consultor e, em seguida, em Criar Novo Consultor.

Inspecione a lista drop-down StatusId. Você verá que agora ela exibe o ID de status e a descrição do registro contido na tabela CONSULTANT_STATUS do banco de dados.

drop down
Figure 27. A lista drop-down StatusId exibe itens de acordo com o método toString() da entidade ConsultantStatus

Solução de Problemas

Dependendo da sua configuração, a implantação da aplicação no servidor poderá falhar e você talvez veja a seguinte mensagem na janela Saída.

GlassFish Server 4 is running.
In-place deployment at /MyDocuments/ConsultingAgency/build/web
GlassFish Server 4, deploy, null, false
/MyDocuments/ConsultingAgency/nbproject/build-impl.xml:1045: The module has not been deployed.
See the server log for details.

A causa mais comum da falha é um problema ao gerar os recursos JDBC no servidor. Se esse for o caso, você provavelmente verá uma mensagem semelhante à seguinte na guia de log do servidor, na janela Saída.

Severe:   Exception while preparing the app : Invalid resource : jdbc/consult__pm
com.sun.appserv.connectors.internal.api.ConnectorRuntimeException: Invalid resource : jdbc/consult__pm

Se a guia de log do servidor não for aberta, será possível abri-la clicando com o botão direito do mouse no nó GlassFish Server, na janela Serviços, e escolhendo Exibir Log do Servidor de Domínio.

Essa aplicação exige dois recursos JDBC:

  • Recurso ou Fonte de Dados JDBC. A aplicação usa a pesquisa JNDI para localizar o recurso JDBC. Se você examinar a unidade de persistência (persistence.xml), poderá ver que o nome da JNDI para a fonte de dados JTA dessa aplicação é jdbc/consult.

O recurso JDBC identifica o pool de conexões atualmente utilizado pela aplicação.

  • Pool de Conexões JDBC. O pool de conexões especifica os detalhes da conexão do banco de dados, o que inclui local, nome do usuário e senha. O pool de conexões usado nessa aplicação é consultPool.

O recurso JDBC e o pool de conexões são especificados no arquivo glassfish-resources.xml. Você pode abrir glassfish-resources.xml no editor expandindo o nó Recursos do Servidor na janela Projetos e clicando duas vezes no arquivo. O arquivo será semelhante ao seguinte:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
  <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="consultPool" non-transactional-connections="false" ping="false" pool-resize-quantity="2" pooling="true" res-type="javax.sql.DataSource" statement-cache-size="0" statement-leak-reclaim="false" statement-leak-timeout-in-seconds="0" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
    <property name="serverName" value="localhost"/>
    <property name="portNumber" value="3306"/>
    <property name="databaseName" value="consult"/>
    <property name="User" value="root"/>
    <property name="Password" value="nb"/>
    <property name="URL" value="jdbc:mysql://localhost:3306/consult?zeroDateTimeBehavior=convertToNull"/>
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
  /<jdbc-connection-pool>
  <jdbc-resource enabled="true" jndi-name="jdbc/consult" object-type="user" pool-name="consultPool"/>
/<resources>

Em glassfish-resources.xml, você poderá ver que o recurso JDBC jdbc/consult identifica consultPool como nome do pool de conexões. É possível também ver as propriedades de consultPool. Nessa aplicação, apenas uma fonte de dados e um pool de conexões são definidos em glassfish-resources.xml. Em alguns casos, convém especificar recursos adicionais, por exemplo, para identificar um armazenamento de dados temporário usado apenas para fins de desenvolvimento ou teste.

Se o recurso JDBC e o pool de conexões não tiverem sido gerados automaticamente no servidor quando você executou a aplicação, será possível realizar as etapas a seguir para criar manualmente os recursos na Console Admin do GlassFish.

  1. Abra glassfish-resources.xml no editor se não tiver feito isso ainda.

Use os valores de propriedade especificados em glassfish-resources.xml ao criar o recurso JDBC e o pool de conexões.

  1. Clique com o botão direito no nó GlassFish Server, na janela Serviços, e escolha Abrir Console Admin do Domínio no menu pop-up para abrir a Console do GlassFish no browser.

  2. No painel de navegação Tarefas Comuns da Console do GlassFish, expanda o nó JDBC e os nós Recursos JDBC e Pool de Conexões JDBC.

gf admin console sm

Você pode ver os recursos JDBC que estão registrados atualmente no servidor. Será necessário criar jdbc/consult e consultPool se não estiverem listados sob o nó JDBC no painel de navegação Tarefas Comuns. Alguns recursos JDBC foram criados por padrão quando você instalou o servidor e são exibidos como subnós.

  1. Clique no nó Pools de Conexões JDBC e clique em Novo no painel Novo Pool de Conexões JDBC.

gf new jdbc pool1
Figure 28. Painel Novo Pool de Conexões JDBC na Console Admin do GlassFish
  1. Digite consultPool como Nome do Pool, selecione javax.sql.ConnectionPoolDataSource como Tipo de Recurso e selecione MySql como Fornecedor do Driver de Banco de Dados. Clique em Próximo.

  2. Na Etapa 2, localize e especifique os valores das propriedades URL, nome do usuário e senha. Clique em Finalizar.

gf new jdbc pool2
Figure 29. Painel Novo Pool de Conexões JDBC na Console Admin do GlassFish

Os valores das propriedades se encontram em glassfish-resources.xml.

O novo pool de conexões é criado no servidor quando você clica em Concluir e um nó do pool de conexões é exibido sob o nó Pools de Conexões JDBC.

  1. Clique no nó Recursos JDBC no painel de navegação Tarefas Comuns e clique em Novo.

  2. Digite jdbc/consult como Nome da JNDI e selecione consultPool na lista drop-down Nome do Pool. Clique em OK.

gf new jdbc resource
Figure 30. Painel Novo Recurso JDBC na Console Admin do GlassFish

O novo recurso JDBC é criado no servidor quando você clica em OK e um nó para o recurso é exibido sob o nó Recursos JDBC.

Na janela Serviço do IDE, você pode expandir o nó Recursos no GlassFish Server e ver se o IDE adicionou os novos recursos. Pode ser necessário atualizar a view (clique com o botão direito do mouse em Recursos e escolha Atualizar) para exibir as alterações.

gf services jdbc resources
Figure 31. Recursos JDBC exibidos na janela Serviços do IDE

Para obter mais dicas sobre solução de problemas ao usar o MySQL e o IDE, consulte os seguintes documentos:

Consulte Também