Informações
| Tipo: | Tutorial |
|---|---|
| Data de Publicação: | 10/12/2007 |
| Revisado em: | 10/12/2007 |
Vote!
Tags Relacionadas
Comentários ( 15 )
Imprimir
Enterprise JavaBeans 3.0: Passo a Passo
por:
Raquel do Carmo (raquelsilva2006@gmail.com)
Tutorial passo a passo para criação de aplicações com EJB 3.0. São abordados os Session Beans e a Java Persistence API.
Objetivos do Tutorial
Ajudar no desenvolvimento das primeiras aplicações, utilizando EJB 3.0. Indicar uma sequência de passos a serem seguidos a fim de compreender os principais mecanismos oferecidos por esse framework.
Passo 1: Configurar o Ambiente
- Jboss AS 4.0.4 instalado com perfil EJB 3.0 (http://labs.jboss.com/jemsinstaller/, baixar o arquivo: 1.2.0.GA)
- Eclipse SDK, versão 3.2 (http://www.eclipse.org/downloads/)
- PostgreSQL, versão 8.2 (http://www.postgresql.org/download/)
- Driver do PostgresSQL (http://jdbc.postgresql.org/download.html, baixar arquivo JDBC3)
Passo 2: Contruir Projeto
Crie um Java Project.
Modifique o Build Path do projeto para referenciar as APIS do JBOSS que estão no diretório jboss-4.0.5.GA\client.
A seguir, uma figura da tela do Eclipse, informando como o projeto deve estar organizado. As classes JAVA serão explicadas nos próximos passos.

Figura 1: Projeto criado no Eclipse
Passo 3: Construir Entidade
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Curso implements Serializable{
@Id @GeneratedValue
private Integer cod;
private String nome;
//.. getters e setters omitidos
}
Listagem 1: Entidade Curso
Essa entidade utiliza anotações presentes na bibliteca do JPA, Java Persistence API.
A anotação @Entity define a classe como persistente. Os cursos serão persistidos na tabela “curso” na base de dados, pois por default o JPA considera o nome da classe igual ao da tabela.
A anotação @Id define o atributo cod como o identificador da tabela no banco de dados
A anotação @ GeneratedValue define que o valor do atributo cod será gerado automaticamente no momento em que os objetos forem persistidos.
Passo 4: Construir Interface
import javax.ejb.Local;
import javax.ejb.Remote;
@Remote
public interface Cadastrar {
void cadCurso(Curso curso);
Collection getCursos();
}
Listagem 2: Interface remota
Características de EJB 3
Antes de criar o Session Bean, é preciso definir suas interfaces de acesso. Um Stateless Session Bean, definido no próximo passo, pode ter uma interface local e remota. Nesse exemplo, a interface é remota.
A anotação @Remote define essa interface como Remota, oferecendo acesso a clientes remotos.
Para declarar uma interface como Local – que não oferece acesso a clientes remotos, deve ser utilizada a anotação @Local. Esse tipo de interface deve ser usado para clientes localizados na mesma JVM onde está rodando o container de EJBs.
Passo 5: Construir Session Bean
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Stateless
public class CadastrarBean implements Cadastrar {
private List cursos;
@PersistenceContext
EntityManager entitymanager;
public CadastrarBean() {
cursos = new ArrayList();
}
public void cadCurso(Curso curso) {
entitymanager.persist(curso);
}
public List getCursos() {
cursos = entitymanager.createQuery("select * from CURSO").getResultList();
return cursos;
}
}
Listagem 3: Session Bean
Características de EJB 3
O Session Bean representa um cliente no servidor J2EE. Para acessar a aplicação, o cliente invoca os métodos do Session Bean. É similar a uma sessão interativa, sendo único para cada cliente. Assim como a sessão, os dados do bean não são armazenados em uma base de dados. Quando o cliente encerra a sessão, o session finaliza e não ficará mais associado a ele.
Existem dois tipo de Session Bean: Stateless e StateFul.
A anotação @Stateless define a classe CadastrarBean como sendo do tipo Stateless. É mais leve e indicado para processos que não necessitam manter estado (valores de atributos) durante as chamadas de métodos.
Para definir o tipo Stateful, é necessário atribuir a anotação @Stateful. Esse bean é mais pesado, mas garante a preservação do estado entre as chamadas de métodos de um mesmo cliente.
A anotação @PersistenceContext, da API de JPA, possibilita o processo de “injeção de dependência”. O container EJB reconhece a anotação e, automaticamente, injeta um objeto EntityManager na propriedade.
Passo 6 : Contruir os arquivos de configuração
Vejamos o arquivo persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="Curso">
<jta-data-source>java:/CursoDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Listagem 4: Arquivo persistence.xml
Esse arquivo deve ser inserido na aplicação, no diretório
META-INF/persistence.xml. O elemento
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>CursoDS</jndi-name>
<connection-url>jdbc:postgresql://localhost:5432/curso</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<user-name>postgres</user-name>
<password>postgres</password>
<metadata>
<type-mapping>PostgreSQL 7.2</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>
Listagem 5: Definição do Data Source
Esse arquivo deve ser inserido dentro do diretório “server\default\deploy” do
JBOSS. Nesse arquivo, são configuradas as propriedades referentes à conexão com o
banco de dados PostgreSQL. O nome “CursoDS” configurado através do elemento
Passo 7: Deploy do projeto
Após ter criado o projeto, exporte para arquivo .jar dentro do diretório jboss-4.0.5.GA/server\default\deploy do JBOSS. Repare que é o mesmo local onde fica armazenado o curso-ds.xml.
Inicie a conexão com o PostgreSQL e crie um banco de dados com o nome “curso”.
Coloque o driver do PostreSQL no diretório jboss-4.0.5.GA2\server\default\lib do JBOSS.
Inicie o JBOSS e confira se o projeto foi “deployado” .
Confira se a tabela curso foi criada no seu banco.
Passo 8: Construir o Cliente
Crie no mesmo projeto a classe abaixo:
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;
public class Cliente {
public static void main(String[] args) throws Exception {
Hashtable prop = new Hashtable();
prop.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
prop.put(InitialContext.PROVIDER_URL,"jnp://localhost:1099");
Context ctx = new InitialContext(prop);
Cadastrar cad = (Cadastrar) ctx.lookup("CadastrarBean/remote");
Curso curso = new Curso();
curso.setNome("AJAX");
cad.cadCurso(curso);
curso.setNome("XML");
cad.cadCurso(curso);
curso.setNome("PROGRAMAÇÃO");
cad.cadCurso(curso);
for(Curso c : cad.getCursos()){
System.out.println(c.getCod() +” - ” + c.getNome());
}
}
}
Listagem 6: Cliente do EJB 3.0
Características de EJB 3
É necessário realizar a conexão com o serviço de nomes, através de um objeto InitialContext da API JNDI (Java Naming and Directory Interface). Através desse objeto, é possível obter um referência para o objeto remoto. Nesse exemplo, o contexto deve ser inicializado por meio de um objeto HashTable. Caso a aplicação fosse construída utilizando um mesmo container, o contexto seria único e conhecido. Então, não seria necessário especificá-lo, possibilitando a inicialização do objeto InitialContext sem parâmetros. Através do método ctx.lookup("nome-da-clase/remote"), um Session Bean remoto é solicitado ao container.
Passo 9: inicializar o Cliente
Agora, é só rodar o cliente e ser feliz !!!
A seguir, a tela do Eclipse com a saída do programa.

Figura 2: Saída do programa
Comentários (15)
- Me ajudou muito...não tinha feito nada em EJB3 ainda...Obrigado.
- postado por Emanoel Tadeu em 21/02/2008 às 23:21
- Muito bom o repasse do seu conhecimento, consegui resolvei um erro do jboss.
- postado por Paula em 20/05/2008 às 23:21
- Olá pessoal, se vcs seguirem o tutorial e der erro ... mudem a consulta para "select c from Curso c"! ok?
- postado por Raquel Carsi em 28/05/2008 às 23:21
- Seguindo o tutorial tive problemas na hora de startar o jboss, aparece isso "--- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM --- ObjectName: jboss.jca:name=CursoDS,service=DataSourceBinding State: NOTYETINSTALLED Depends On Me: persistence.units:jar=ProjetoEJB.jar,unitName=Curso" e não cria a tabela no banco, alguém sabe pq? podem mandar para o meu e-mail danielbchaves@yahoo.com.br
- postado por Daniel em 03/06/2008 às 23:21
- Favor me explicar o porque que "select c from Curso c" faria o cod funcionar, porque se você pensar em BD esta query acima não funcionaria, só se fosse "select c.* from Curso c". O entity transforma o resultado em um tipo generics?? Favor explicar melhor o pq do mudar a consulta. Obrigado
- postado por Logan em 04/06/2008 às 23:21
- Logan, de acordo com o JPA a outra consulta que eu fiz nao deveria funcionar... (nem me pergunte pq funcionou =/ ).. pq o certo é colocar, na consulta, o mesmo nome da entidade sem variar nem maiúsculas nem minúsculas. Outra coisa ... as consultas em JPA são feitas na linguagem de consulta EJB-QL ... que é diferente da SQL ok?
- postado por Raquel em 26/06/2008 às 23:21
- Daniel, vc provavelmente esqueceu de colocar o arquivo curso-ds.xml, citado no passo 6.
- postado por Raquel em 26/06/2008 às 23:21
- muito bom
- postado por Gabriel em 24/07/2008 às 23:21
- Parabéns Raquel, mto bom. Inicialmente eu tive o mesmo problema do Daniel, mas depois eu descobri que estava gerando o .jar com a opção errada(General -> Archive File). Depois que eu passei para a opção Java -> JAR File deu tudo certo. PS: Uso o Eclipse Europa
- postado por Rodrigo Dantas em 08/08/2008 às 23:21
-
Pessoal encontrei o erro abaixo. Estou usando JBoss 4.2. Alguém pode me ajudar?
log4j:WARN No appenders could be found for logger (org.jnp.interfaces.NamingContext).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" javax.naming.CommunicationException: Could not obtain connection to any of these urls: localhost:8088 and discovery failed with error: javax.naming.CommunicationException: Receive timed out [Root exception is java.net.SocketTimeoutException: Receive timed out] [Root exception is javax.naming.CommunicationException: Failed to connect to server localhost:8088 [Root exception is javax.naming.ServiceUnavailableException: Failed to connect to server localhost:8088 [Root exception is java.net.ConnectException: Connection refused: connect]]]
at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1416)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:596)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:589)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at Cliente.main(Cliente.java:17)
Caused by: javax.naming.CommunicationException: Failed to connect to server localhost:8088 [Root exception is javax.naming.ServiceUnavailableException: Failed to connect to server localhost:8088 [Root exception is java.net.ConnectException: Connection refused: connect]]
at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:269)
at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1387)
... 4 more
Caused by: javax.naming.ServiceUnavailableException: Failed to connect to server localhost:8088 [Root exception is java.net.ConnectException: Connection refused: connect]
at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:243)
... 5 more
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at java.net.Socket.
(Socket.java:366) at java.net.Socket. (Socket.java:266) at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:84) at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:77) at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:239) ... 5 more - postado por Celso Romão Cardoso de Almeida Júnior em 13/08/2008 às 23:21
- Pessoal! Não estou conseguindo conectar. estou usando o JBoss 4.2. O que significa estas Strings: org.jnp.interfaces.NamingContextFactory jnp://localhost:1099
- postado por Celso Romão Cardoso de Almeida Júnior em 13/08/2008 às 23:21
- Olá Celso, será que você não está usando a porta 8080 em outro programa? Você tem que deixar essa porta aberta pra poder rodar o JBOSS!
- postado por Raquel do Carmo em 10/09/2008 às 23:21
- A medida que se vai querendo desenvolver coisas mais robustas ou complexas nasce a necessidade de arquiteturas mais adequadas. Pois bem, tenho me enrolado para construir aplicações Enterprise (EAR) usando o eclipse. Aqui vai um pepido de um tutorial para a construção de uma aplicação EAR, que utilize os wizards do eclipse: projeto JPA para as entidades, EJB project para EJBs, ai explicando como criar módulo e os Session Bean. Nesta caso seria interessante como criar cliente de teste para os beans: entity e session tanto local como remotamente. Dynamic web project para o cliente web. e o mais importante de tudo descrever os descritores de deploy de cada projeto, qual a sua localização dentro de cada projeto e por fim e talvés o que mais confunda a contrução de um enterprise application project (EAR): sua construção do descritor como juntar os módulos a ele e testar pelo eclipse e depois o build. Acho que estou pedindo demais ne ... :) Mas é apenas o pedido de alguém interessado em aprender as coisas seguindo uma boa engenharia e arquitetura. Obrigado pela atenção.
- postado por Alessandro B. Moreira em 15/10/2008 às 23:21
-
Só uma observação:
Não sei se aconteceu só comigo, mas uso o JDK 6 e no passo 4, tive que mudar para:
Collection
getCursos(); Pq no passo 8, pra mim ocorria erro, pois o compilador interpretava o cad.getCursos() -passo 8- como um Objeto e não podia converter para a entidade Curso. - postado por Diogo Roos em 26/10/2008 às 23:21
- Mesmo seguindo o tutorial, meu projeto deu erro. O NetBeans acaba nao reconhecendo algumas expressões(esclamação). Se eu conseguir resolver esse problema postarei aqi mais tarde. Obrigado
- postado por Elson em 31/10/2008 às 23:21
