EJB - Guia Rápido

EJB significa Enterprise Java Beans. EJB é uma parte essencial de uma plataforma J2EE. A plataforma J2EE possui arquitetura baseada em componentes para fornecer recursos de várias camadas, distribuídos e altamente transacionais para aplicativos de nível empresarial.

O EJB fornece uma arquitetura para desenvolver e implantar aplicativos corporativos baseados em componentes, considerando robustez, alta escalabilidade e alto desempenho. Um aplicativo EJB pode ser implementado em qualquer servidor de aplicativos compatível com a especificação padrão J2EE 1.3.

Discutiremos o EJB 3.0 em detalhes neste tutorial.

Tipos

O EJB é basicamente dividido em três categorias; A tabela a seguir lista seus nomes com breves descrições -

S.No Tipo e descrição
1

Session Bean

O bean de sessão armazena dados de um determinado usuário para uma única sessão. Pode serstateful ou stateless. É menos intensivo em recursos em comparação com o bean de entidade. O bean de sessão é destruído assim que a sessão do usuário termina.

2

Entity Bean

Entity beansrepresentam armazenamento de dados persistente. Os dados do usuário podem ser salvos no banco de dados por meio de beans de entidade e, posteriormente, podem ser recuperados do banco de dados no bean de entidade.

3

Message Driven Bean

Message driven beanssão usados ​​no contexto do JMS (Java Messaging Service). Message Driven Beans pode consumir mensagens JMS de entidades externas e agir de acordo.

Benefícios

A seguir estão os benefícios importantes do EJB -

  • Desenvolvimento simplificado de aplicativo de nível empresarial em grande escala.

  • O servidor de aplicativos / contêiner EJB fornece a maioria dos serviços de nível de sistema, como manipulação de transações, criação de log, balanceamento de carga, mecanismo de persistência, manipulação de exceção e assim por diante. O desenvolvedor deve se concentrar apenas na lógica de negócios do aplicativo.

  • O contêiner EJB gerencia o ciclo de vida das instâncias EJB, portanto, o desenvolvedor não precisa se preocupar com quando criar / excluir objetos EJB.

EJB é uma estrutura para Java, então o primeiro requisito é ter um Java Ddesenvolvimento K(JDK) instalado em sua máquina.

Requisitos do sistema

JDK 1,5 ou superior.
Memória nenhum requisito mínimo.
Espaço em disco nenhum requisito mínimo.
Sistema operacional nenhum requisito mínimo.

Etapa 1 - Verifique a instalação do Java em seu sistema

Agora abra o console e execute o seguinte java comando.

SO Tarefa Comando
janelas Abrir console de comando c: \> versão java
Linux Abra o terminal de comando $ java -version
Mac Terminal aberto máquina: ~ joseph $ java -version

Vamos verificar a saída de todos os sistemas operacionais -

SO Resultado
janelas

versão java "1.6.0_21"

Java (TM) SE Runtime Environment (build 1.6.0_21-b11)

Servidor VM Java HotSpot (TM) de 64 bits (versão 23.21-b01, modo misto)

Linux

versão java "1.6.0_21"

Java (TM) SE Runtime Environment (build 1.6.0_21-b11)

Servidor VM Java HotSpot (TM) de 64 bits (versão 23.21-b01, modo misto)

Mac

versão java "1.6.0_21"

Java (TM) SE Runtime Environment (build 1.6.0_21-b11)

Servidor VM Java HotSpot (TM) de 64 bits (versão 23.21-b01, modo misto)

Se você não tiver o Java instalado, instale o Java Software Development Kit (SDK) em www.oracle.com . Estamos assumindo que o Java 1.6.0_21 é a versão instalada para este tutorial.

Etapa 2 - Definir o ambiente JAVA

Colocou o JAVA_HOMEvariável de ambiente para apontar o local do diretório base onde o Java está instalado em seu sistema. Por exemplo,

SO Resultado
janelas Defina a variável de ambiente JAVA_HOME como C: \ Arquivos de programas \ Java \ jdk1.6.0_21
Linux export JAVA_HOME = / usr / local / java-current
Mac export JAVA_HOME = / Library / Java / Home

Anexe a localização do compilador Java ao caminho do sistema.

SO Resultado
janelas Anexe a string; C: \ Arquivos de programas \ Java \ jdk1.6.0_21 \ bin ao final da variável do sistema, Caminho.
Linux exportar PATH =$PATH:$JAVA_HOME / bin /
Mac não requerido

Verifique a instalação do Java usando java -version comando explicado acima.

Etapa 3 - Baixe e instale o NetBeans IDE

Baixe a versão mais recente do NetBeans IDE em netbeans.org . No momento em que escrevi este tutorial, eu baixei o Netbeans 7.3 que vem com o JDK 1.7 usando o seguinte link www.oracle.com

SO Nome do instalador
janelas Netbeans 7.3
Linux Netbeans 7.3
Mac Netbeans 7.3

Etapa 4 - Configurar o servidor de aplicativos JBoss

Você pode baixar a versão mais recente do JBoss Server em www.jboss.org . Baixe o arquivo de acordo com a plataforma. Extraia o Jboss para qualquer local em sua máquina.

SO Nome do arquivo
janelas jboss-5.1.0.GA-jdk6.zip
Linux jboss-5.1.0.GA-src.tar.gz
Mac jboss-5.1.0.GA-src.tar.gz

Etapa 5 - Configurar Plug-ins JEE para Netbeans

Abra a janela Plug-in usando Ferramentas> Plug-ins. Abra a guia "Plug-in disponível" e selecione "Java EE Base" e "EJB e EAR" na categoria "Java Web e EE". Clique no botão instalar. O Netbeans irá baixar e instalar os respectivos plug-ins. Verifique a instalação dos plug-ins usando a guia "Instalado" (conforme mostrado na imagem abaixo).

Etapa 6 - Configurar o servidor JBoss no Netbeans

Vá para a guia Serviços e clique com o botão direito nos servidores para adicionar um novo servidor.

O assistente Adicionar instância do servidor será aberto. Selecione JBoss e na próxima etapa insira os detalhes relevantes para configurar o servidor no netbeans.

Depois que tudo estiver configurado, você verá a seguinte tela.

Etapa 7 - Instale o servidor de banco de dados (PostGreSql)

Baixe a versão mais recente do servidor de banco de dados PostGreSql em www.postgresql.org . No momento em que escrevo este tutorial, eu baixei o PostGreSql 9.2

SO Nome do instalador
janelas PostGreSql 9.2
Linux PostGreSql 9.2
Mac PostGreSql 9.2

Para criar um módulo EJB simples, usaremos o NetBeans, assistente "Novo projeto". No exemplo fornecido a seguir, criaremos um projeto de módulo EJB denominado Component.

Criar Projeto

No NetBeans IDE, selecione File > New Project >. Você verá a seguinte tela

Selecione o tipo de projeto na categoria Java EE, Tipo de projeto como EJB Module. CliqueNext >botão. Você verá a seguinte tela.

Insira o nome e o local do projeto. CliqueNext >botão. Você verá a seguinte tela.

Selecione o servidor como JBoss Application Server. CliqueFinishbotão. Você verá o seguinte projeto criado pelo NetBeans.

Crie um EJB de amostra

Para criar um EJB simples, usaremos o assistente "Novo" do NetBeans. No exemplo fornecido a seguir, criaremos uma classe EJB sem estado chamada librarySessionBean no projeto EjbComponent.

Selecione o projeto EjbComponent na janela do explorador de projetos e clique com o botão direito nele. Selecione,New > Session Bean. Você verá oNew Session Bean Mago.

Insira o nome do bean de sessão e o nome do pacote. CliqueFinishbotão. Você verá as seguintes classes EJB criadas pelo NetBeans.

  • LibrarySessionBean - bean de sessão sem estado

  • LibrarySessionBeanLocal - interface local para bean de sessão

Estou mudando a interface local para a interface remota, pois vamos acessar nosso EJB em um aplicativo baseado em console. A interface remota / local é usada para expor métodos de negócios que um EJB precisa implementar.

LibrarySessionBeanLocal foi renomeado para LibrarySessionBeanRemote e LibrarySessionBean implementa a interface LibrarySessionBeanRemote.

LibrarySessionBeanRemote

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibrarySessionBean

package com.tutorialspoint.stateless;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
 
@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
   
   List<String> bookShelf;    
   
   public LibrarySessionBean() {
      bookShelf = new ArrayList<String>();
   }
    
   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    
 
   public List<String> getBooks() {
      return bookShelf;
   }
}

Construir o Projeto

  • Selecione o projeto EjbComponent na janela Project Explorer.
  • Clique com o botão direito para abrir o menu de contexto.
  • Selecione limpar e construir.

Você verá a seguinte saída na saída do console do NetBeans.

ant -f C:\\EJB\\EjbComponent clean dist
init:
undeploy-clean:
deps-clean:
Deleting directory C:\EJB\EjbComponent\build
Deleting directory C:\EJB\EjbComponent\dist
clean:
init:
deps-jar:
Created dir: C:\EJB\EjbComponent\build\classes
Copying 3 files to C:\EJB\EjbComponent\build\classes\META-INF
Created dir: C:\EJB\EjbComponent\build\empty
Created dir: C:\EJB\EjbComponent\build\generated-sources\ap-source-output
Compiling 2 source files to C:\EJB\EjbComponent\build\classes
warning: [options] bootstrap class path not set in conjunction with -source 1.6
Note: C:\EJB\EjbComponent\src\java\com\tutorialspoint\stateless
\LibraryPersistentBean.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 warning
compile:
library-inclusion-in-archive:
Created dir: C:\EJB\EjbComponent\dist
Building jar: C:\EJB\EjbComponent\dist\EjbComponent.jar
dist:
BUILD SUCCESSFUL (total time: 3 seconds)

Inicie o servidor de aplicativos

  • Selecione o servidor de aplicativos JBoss na janela Servidores na janela Serviços.
  • Clique com o botão direito para abrir o menu de contexto.
  • Selecione iniciar.

Você verá a seguinte saída no NetBeans, saída no JBoss Application Server.

Calling C:\jboss-5.1.0.GA\bin\run.conf.bat
=========================================================================
 
   JBoss Bootstrap Environment
 
   JBOSS_HOME: C:\jboss-5.1.0.GA
 
   JAVA: C:\Program Files (x86)\Java\jdk1.6.0_21\bin\java
 
   JAVA_OPTS: -Dprogram.name=run.bat -Xms128m -Xmx512m -server
 
   CLASSPATH: C:\jboss-5.1.0.GA\bin\run.jar
 
=========================================================================
 
16:25:50,062 INFO  [ServerImpl] Starting JBoss (Microcontainer)...
16:25:50,062 INFO  [ServerImpl] Release ID: JBoss 
   [The Oracle] 5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)
...
 
16:26:40,420 INFO  [TomcatDeployment] deploy, ctxPath=/admin-console
16:26:40,485 INFO  [config] Initializing Mojarra (1.2_12-b01-FCS) for context '/admin-console'
16:26:42,362 INFO  [TomcatDeployment] deploy, ctxPath=/
16:26:42,406 INFO  [TomcatDeployment] deploy, ctxPath=/jmx-console
16:26:42,471 INFO  [Http11Protocol] Starting Coyote HTTP/1.1 on http-127.0.0.1-8080
16:26:42,487 INFO  [AjpProtocol] Starting Coyote AJP/1.3 on ajp-127.0.0.1-8009
16:26:42,493 INFO  [ServerImpl] JBoss (Microcontainer) 
   [5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)] Started in 52s:427ms

Implantar o Projeto

  • Selecione o projeto EjbComponent na janela Project Explorer.
  • Clique com o botão direito para abrir o menu de contexto.
  • Selecione Implementar.

Você verá a seguinte saída na saída do console do NetBeans.

ant -f C:\\EJB\\EjbComponent -DforceRedeploy=true -Ddirectory.deployment.supported=false -Dnb.wait.for.caches=true run
init:
deps-jar:
compile:
library-inclusion-in-archive:
Building jar: C:\EJB\EjbComponent\dist\EjbComponent.jar
dist-directory-deploy:
pre-run-deploy:
Checking data source definitions for missing JDBC drivers...
Distributing C:\EJB\EjbComponent\dist\EjbComponent.jar to [org.jboss.deployment.spi.LocalhostTarget@1e4f84ee]
Deploying C:\EJB\EjbComponent\dist\EjbComponent.jar
Application Deployed
Operation start started
Operation start completed
post-run-deploy:
run-deploy:
run:
BUILD SUCCESSFUL (total time: 2 seconds)

Saída de log do servidor de aplicativos JBoss

16:30:00,963 INFO  [DeployHandler] Begin start, [EjbComponent.jar]
...
16:30:01,233 INFO  [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@12038795{vfszip:/C:/jboss-5.1.0.GA/server/default/deploy/EjbComponent.jar/}
...
16:30:01,281 INFO  [JBossASKernel]    jndi:LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote
16:30:01,281 INFO  [JBossASKernel]    Class:com.tutorialspoint.stateless.LibrarySessionBeanRemote
16:30:01,281 INFO  [JBossASKernel]    jndi:LibrarySessionBean/remote
16:30:01,281 INFO  [JBossASKernel]  Added bean(jboss.j2ee:jar=EjbComponent.jar,name=
LibrarySessionBean,service=EJB3) to KernelDeployment of: EjbComponent.jar
16:30:01,282 INFO  [JBossASKernel] installing bean: jboss.j2ee:jar=EjbComponent.jar,name=BookMessageHandler,service=EJB3
16:30:01,282 INFO  [JBossASKernel]   with dependencies:
16:30:01,282 INFO  [JBossASKernel]   and demands:
16:30:01,282 INFO  [JBossASKernel]    jboss.ejb:service=EJBTimerService
...
16:30:01,283 INFO  [EJB3EndpointDeployer] Deploy 
AbstractBeanMetaData@5497cb{name=jboss.j2ee:jar=EjbComponent.jar, 
name=LibrarySessionBean, service=EJB3_endpoint bean=org.jboss.ejb3.endpoint.deployers.impl.EndpointImpl properties=[container] constructor=null autowireCandidate=true}
...
16:30:01,394 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:01,395 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
 
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface

Crie o cliente para acessar o EJB

  • No NetBeans IDE, selecione File > New Project >.

  • Selecione o tipo de projeto na categoria Java, Tipo de projeto como Java Application. Clique em Avançar> botão

  • Insira o nome e o local do projeto. CliqueFinish >botão. Escolhemos o nome como EjbTester.

  • Clique com o botão direito no nome do projeto na janela Project explorer. Selecioneproperties.

  • Adicionar projeto de componente EJB criado anteriormente em bibliotecas usando Add Project botão em compile aba.

  • Adicionar bibliotecas jboss usando Add jar/folder botão em compileaba. As bibliotecas Jboss podem ser localizadas na <pasta de instalação do jboss >> pasta do cliente.

Crie jndi.properties no projeto, digamos, EjbTester.

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost

Crie o pacote com.tutorialspoint.test e a classe EJBTester.java sob ele.

EJBTester.java

package com.tutorialspoint.test;
 
import com.tutorialspoint.stateless.LibrarySessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
 
public class EJBTester {
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testStatelessEjb();
   }
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   private void testStatelessEjb() {
      try {
         int choice = 1; 
         LibrarySessionBeanRemote libraryBean = 
         (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();                    
               libraryBean.addBook(bookName);          
            }else if (choice == 2) {
               break;
            }
         }
         List<String> booksList = libraryBean.getBooks();
         System.out.println("Book(s) entered so far: " + booksList.size());
         for (int i = 0; i < booksList.size(); ++i) {
            System.out.println((i+1)+". " + booksList.get(i));
         }
         LibrarySessionBeanRemote libraryBean1 = 
         (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
         List<String> booksList1 = libraryBean1.getBooks();
         System.out.println(
            "***Using second lookup to get library stateless object***");
         System.out.println(
            "Book(s) entered so far: " + booksList1.size());
         for (int i = 0; i < booksList1.size(); ++i) {
            System.out.println((i+1)+". " + booksList1.get(i));
         }
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      } finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }  
}

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateless object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)

Nos capítulos a seguir, abordaremos vários aspectos desse aplicativo EJB completo.

Um bean de sessão stateless é um tipo de bean corporativo, que normalmente é usado para realizar operações independentes. Um bean de sessão stateless de acordo com seu nome não tem nenhum estado de cliente associado, mas pode preservar seu estado de instância. O contêiner EJB normalmente cria um conjunto de poucos objetos de bean sem estado e usa esses objetos para processar a solicitação do cliente. Por causa do pool, os valores das variáveis ​​de instância não têm garantia de serem os mesmos em pesquisas / chamadas de método.

Etapas para criar um EJB sem estado

A seguir estão as etapas necessárias para criar um EJB sem estado -

  • Crie uma interface remota / local expondo os métodos de negócios.

  • Essa interface será usada pelo aplicativo cliente EJB.

  • Use a anotação @Local, se o cliente EJB estiver no mesmo ambiente em que o bean de sessão EJB deve ser implementado.

  • Use a anotação @Remote, se o cliente EJB estiver em um ambiente diferente onde o bean de sessão EJB deve ser implementado.

  • Crie um bean de sessão sem estado, implementando a interface acima.

  • Use a anotação @Stateless para significar um bean sem estado. O contêiner EJB cria automaticamente as configurações relevantes ou interfaces exigidas lendo esta anotação durante a implantação.

Interface Remota

import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   //add business method declarations
}

EJB sem estado

@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
   //implement business method 
}

Aplicação de exemplo

Vamos criar um aplicativo de teste EJB para testar EJB sem estado.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.stateless conforme explicado no capítulo EJB - Criar Aplicativo . Você também pode usar o projeto criado no capítulo EJB - Criar Aplicativo como tal para este capítulo para entender os conceitos de EJB sem estado.

2

Crie LibrarySessionBean.java e LibrarySessionBeanRemote conforme explicado no capítulo EJB - Criar aplicativo . Mantenha o resto dos arquivos inalterados.

3

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

4

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

5

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

EJBComponent (Módulo EJB)

LibrarySessionBeanRemote.java

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibrarySessionBean.java

package com.tutorialspoint.stateless;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
 
@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
    
   List<String> bookShelf;    
 
   public LibrarySessionBean() {
      bookShelf = new ArrayList<String>();
   }
 
   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    
 
   public List<String> getBooks() {
      return bookShelf;
   }
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibrarySessionBean/remote.

  • Estaremos usando esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.stateless.LibrarySessionBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBeanRemote ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
 
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibrarySessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testStatelessEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testStatelessEjb() {
 
      try {
         int choice = 1; 
 
         LibrarySessionBeanRemote libraryBean =
         LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }       
         LibrarySessionBeanRemote libraryBean1 = 
            (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
         List<String> booksList1 = libraryBean1.getBooks();
         System.out.println(
            "***Using second lookup to get library stateless object***");
         System.out.println(
            "Book(s) entered so far: " + booksList1.size());
         for (int i = 0; i < booksList1.size(); ++i) {
            System.out.println((i+1)+". " + booksList1.get(i));
         }		 
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testStatelessEjb (), a consulta jndi é feita com o nome - "LibrarySessionBean / remote" para obter o objeto de negócios remoto (ejb sem estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir a opção.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está armazenando o livro em sua variável de instância.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão sem estado e sai.

  • Em seguida, outra pesquisa jndi é feita com o nome - "LibrarySessionBean / remote" para obter o objeto de negócios remoto (EJB sem estado) novamente e a listagem de livros é feita.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateless object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)

Execute o cliente novamente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 0
***Using second lookup to get library stateless object***
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 12 seconds)
  • A saída mostrada acima pode variar, dependendo de quantos objetos EJB sem estado o JBoss está mantendo.

  • No caso, um único objeto EJB sem estado é mantido, você pode ver a mesma lista de livros após cada consulta.

  • O contêiner EJB pode retornar o mesmo objeto EJB sem estado para cada consulta.

  • O bean EJB sem estado está mantendo o valor da variável de instância até que o servidor não seja reiniciado.

Um bean de sessão com estado é um tipo de bean corporativo, que preserva o estado de conversação com o cliente. Um bean de sessão com estado de acordo com seu nome mantém o estado do cliente associado em suas variáveis ​​de instância. O EJB Container cria um bean de sessão com estado separado para processar cada solicitação do cliente. Assim que o escopo da solicitação termina, o bean de sessão statelful é destruído.

Etapas para criar EJB com estado

A seguir estão as etapas necessárias para criar um EJB com estado -

  • Crie uma interface remota / local expondo os métodos de negócios.

  • Essa interface será usada pelo aplicativo cliente EJB.

  • Use a anotação @Local se o cliente EJB estiver no mesmo ambiente em que o bean de sessão EJB precisa ser implementado.

  • Use a anotação @Remote se o cliente EJB estiver em um ambiente diferente onde o bean de sessão EJB precisa ser implementado.

  • Crie um bean de sessão com estado, implementando a interface acima.

  • Use a anotação @Stateful para significar um bean com estado. O contêiner EJB cria automaticamente as configurações relevantes ou interfaces exigidas lendo esta anotação durante a implantação.

Interface Remota

import javax.ejb.Remote;
 
@Remote
public interface LibraryStatefulSessionBeanRemote {
   //add business method declarations
}

EJB com estado

@Stateful
public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote {
   //implement business method 
}

Aplicação de exemplo

Vamos criar um aplicativo de teste EJB para testar EJB com estado.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.stateful conforme explicado no capítulo EJB - Criar Aplicativo . Você também pode usar o projeto criado no capítulo EJB - Criar Aplicativo como tal para este capítulo para compreender os conceitos de EJB com estado.

2

Crie LibraryStatefulSessionBean.java e LibraryStatefulSessionBeanRemote conforme explicado no capítulo EJB - Criar aplicativo . Mantenha o resto dos arquivos inalterados.

3

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

4

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

5

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

EJBComponent (Módulo EJB)

LibraryStatefulSessionBeanRemote.java

package com.tutorialspoint.stateful;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibraryStatefulSessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibraryStatefulSessionBean.java

package com.tutorialspoint.stateful;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateful;
 
@Stateful
public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote {
    
   List<String> bookShelf;    
 
   public LibraryStatefulSessionBean() {
      bookShelf = new ArrayList<String>();
   }
 
   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    
 
   public List<String> getBooks() {
      return bookShelf;
   }
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryStatefulSessionBean/remote.

  • Estaremos usando esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryStatefulSessionBean/remote - EJB3.x Default Remote Business Interface
   LibraryStatefulSessionBean/remote-com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryStatefulSessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote ejbName: LibraryStatefulSessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
 
   LibraryStatefulSessionBean/remote - EJB3.x Default Remote Business Interface
   LibraryStatefulSessionBean/remote-com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial = org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs = org.jboss.naming:org.jnp.interfaces
java.naming.provider.url = localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão com preservação de estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testStatelessEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testStatelessEjb() {
 
      try {
         int choice = 1; 
 
         LibraryStatefulSessionBeanRemote libraryBean =
         LibraryStatefulSessionBeanRemote)ctx.lookup("LibraryStatefulSessionBean/remote");
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }       
         LibraryStatefulSessionBeanRemote libraryBean1 = 
            (LibraryStatefulSessionBeanRemote)ctx.lookup("LibraryStatefulSessionBean/remote");
         List<String> booksList1 = libraryBean1.getBooks();
         System.out.println(
            "***Using second lookup to get library stateful object***");
         System.out.println(
            "Book(s) entered so far: " + booksList1.size());
         for (int i = 0; i < booksList1.size(); ++i) {
            System.out.println((i+1)+". " + booksList1.get(i));
         }		 
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testStatefulEjb (), a pesquisa jndi é feita com o nome - "LibraryStatefulSessionBean / remote" para obter o objeto de negócios remoto (ejb com estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão com preservação de estado. O Session Bean está armazenando o livro em sua variável de instância.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão com preservação de estado e sai.

  • Em seguida, outra pesquisa jndi é feita com o nome - "LibraryStatefulSessionBean / remote" para obter o objeto de negócios remoto (EJB com estado) novamente e a listagem de livros é feita.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console Netbeans -

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateful object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)

Execute o cliente novamente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 0
***Using second lookup to get library stateful object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 12 seconds)
  • A saída mostrada acima afirma que, para cada consulta, uma instância EJB com estado diferente é retornada.

  • O objeto EJB stateful está mantendo o valor apenas para uma única sessão. Como na segunda execução, não estamos obtendo nenhum valor de livros.

EJB 3.0, bean de entidade usado no EJB 2.0, foi amplamente substituído pelo mecanismo de persistência. Agora, o bean de entidade é um POJO simples com mapeamento com tabela.

A seguir estão os principais atores na API de persistência -

  • Entity- Um objeto persistente que representa o registro do armazenamento de dados. É bom ser serializável.

  • EntityManager- Interface de persistência para fazer operações de dados como adicionar / excluir / atualizar / localizar um objeto persistente (entidade). Também ajuda a executar consultas usandoQuery interface.

  • Persistence unit (persistence.xml) - Unidade de persistência descreve as propriedades do mecanismo de persistência.

  • Data Source (*ds.xml)- Fonte de dados descreve as propriedades relacionadas ao armazenamento de dados, como url de conexão. nome de usuário, senha etc.

Para demonstrar o mecanismo de persistência EJB, precisamos fazer as seguintes tarefas -

  • Step 1 - Crie uma tabela no banco de dados.

  • Step 2 - Crie a classe Entity correspondente à tabela.

  • Step 3 - Criar fonte de dados e unidade de persistência.

  • Step 4 - Crie um EJB sem estado com instância EntityManager.

  • Step 5- Atualize o EJB sem estado. Adicione métodos para adicionar registros e obter registros do banco de dados por meio do gerenciador de entidades.

  • Step 6 - Um cliente de aplicativo baseado em console acessará o EJB sem estado para persistir os dados no banco de dados.

Criar a tabela

Crie uma mesa books no banco de dados padrão postgres.

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

Criar classe Entity

//mark it entity using Entity annotation 
//map table name using Table annotation
@Entity
@Table(name="books")
public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }

   //mark id as primary key with autogenerated value
   //map database column id with id field
   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }
   ...
}

Criar DataSource e Unidade de Persistência

DataSource (jboss-ds.xml)

<?xml version = "1.0" encoding = "UTF-8"?>
<datasources>
   <local-tx-datasource>
      <jndi-name>PostgresDS</jndi-name>
      <connection-url>jdbc:postgresql://localhost:5432/postgres</connection-url>
      <driver-class>org.postgresql.driver</driver-class>
      <user-name>sa</user-name>
      <password>sa</password>
      <min-pool-size>5</min-pool-size>
      <max-pool-size>20</max-pool-size>
      <idle-timeout-minutes>5</idle-timeout-minutes>
   </local-tx-datasource>
</datasources>

Unidade de persistência (persistence.xml)

<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 = "EjbComponentPU" transaction-type = "JTA">
      <jta-data-source>java:/PostgresDS</jta-data-source>
      <exclude-unlisted-classes>false</exclude-unlisted-classes>
      <properties/>
   </persistence-unit>
   
   <persistence-unit name = "EjbComponentPU2" transaction-type = "JTA">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>java:/PostgresDS</jta-data-source>
      <exclude-unlisted-classes>false</exclude-unlisted-classes>
	  
      <properties>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
      </properties>
   </persistence-unit>
   
</persistence>

Criar EJB sem estado com instância EntityManager

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   //pass persistence unit to entityManager.
   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {        
      return entityManager.createQuery("From Books").getResultList();
   }
   ...
}

Depois de construir o módulo EJB, precisamos de um cliente para acessar o bean sem estado, que criaremos na próxima seção.

Aplicação de exemplo

Vamos criar um aplicativo EJB de teste para testar o mecanismo de persistência EJB.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo . Você também pode usar o projeto criado no capítulo EJB - Criar Aplicativo como tal para este capítulo para entender os conceitos de persistência EJB.

2

Crie Book.java no pacote com.tutorialspoint.entity e modifique-o conforme mostrado abaixo.

3

Crie LibraryPersistentBean.java e LibraryPersistentBeanRemote conforme explicado nos capítulos EJB - Criar Aplicativo e modifique-os conforme mostrado abaixo.

4

Crie jboss-ds.xml emEjbComponent > setup pasta e persistence.xml emEjbComponent > src > conf pasta. Essas pastas podem ser vistas na guia de arquivos do Netbeans. Modifique esses arquivos conforme mostrado acima.

5

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

6

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

7

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB. Modifique-o conforme mostrado abaixo.

EJBComponent (Módulo EJB)

Book.java

package com.tutorialspoint.entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="books")
public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }

   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

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

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryPersistentBean/remote.

  • Estaremos usando esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEntityEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEntityEjb() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean =
         LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas.

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testStatefulEjb (), a pesquisa jndi é feita com o nome - "LibraryStatefulSessionBean / remote" para obter o objeto de negócios remoto (ejb com estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir a opção.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está mantendo o livro no banco de dados por meio da chamada EntityManager.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão com preservação de estado e sai.

  • Em seguida, outra pesquisa jndi é feita com o nome - "LibraryStatelessSessionBean / remote" para obter o objeto de negócios remoto (EJB sem estado) novamente e a listagem de livros é feita.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console Netbeans -

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn java
BUILD SUCCESSFUL (total time: 15 seconds)

Execute o cliente novamente para acessar o EJB

Reinicie o JBoss antes de acessar o EJB.

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Spring
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
2. Learn Spring
BUILD SUCCESSFUL (total time: 15 seconds)

A saída mostrada acima afirma que os livros estão sendo armazenados em armazenamento persistente e são recuperados do banco de dados.

Um bean acionado por mensagem é um tipo de bean corporativo, que é invocado pelo contêiner EJB ao receber uma mensagem da fila ou tópico. O bean controlado por mensagem é um bean sem estado e é usado para realizar tarefas de forma assíncrona.

Para demonstrar o uso do bean orientado por mensagem, faremos uso do capítulo de persistência EJB e precisamos fazer as seguintes tarefas -

  • Step 1- Criar tabela no banco de dados (consulte o capítulo Persistência EJB ).

  • Step 2- Criar classe de Entidade correspondente à tabela (consulte o capítulo EJB-Persistência ).

  • Step 3- Criar DataSource e Unidade de Persistência (consulte o capítulo EJB-Persistência ).

  • Step 4- Crie um EJB sem estado que tenha uma instância EntityManager (consulte o capítulo EJB-Persistência ).

  • Step 5- Atualizar métodos ejb.Add sem estado para adicionar registros e obter registros do banco de dados por meio do gerenciador de entidades (consulte o capítulo Persistência EJB ).

  • Step 6 - Crie uma fila chamada BookQueue em JBoss default diretório de aplicativos.

  • Step 7 - Um cliente de aplicativo baseado em console enviará mensagem para esta fila.

  • Step 8 - Crie um bean controlado por mensagem, que usará o bean sem estado para persistir os dados do cliente.

  • Step 9 - O contêiner EJB do jboss chamará o bean acionado por mensagem acima e passará a mensagem que o cliente enviará.

Criar fila

Crie um arquivo chamado jbossmq-destinos-service.xml se não existir em <JBoss Installation Folder> > server > default > deploy pasta.

Aqui estamos criando uma fila chamada BookQueue -

jbossmq-Destinations-service.xml

<mbean code="org.jboss.mq.server.jmx.Queue"  
   name="jboss.mq.destination:service=Queue,name=BookQueue">  
   <depends optional-attribute-name="DestinationManager">
      jboss.mq:service=DestinationManager
   </depends>  
</mbean>

Ao iniciar o JBoss, você verá uma entrada semelhante no log do jboss.

...
10:37:06,167 INFO  [QueueService] Queue[/queue/BookQueue] started, fullSize=200000, pageSize=2000, downCacheSize=2000
...

Criar bean acionado por mensagem

@MessageDriven(
   name = "BookMessageHandler",
   activationConfig = {
      @ActivationConfigProperty( propertyName = "destinationType", 
                                 propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty( propertyName = "destination", 
                                 propertyValue ="/queue/BookQueue")
   }
)
public class LibraryMessageBean implements MessageListener {
 
   @Resource
   private MessageDrivenContext mdctx;  
 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
 
   public LibraryMessageBean() {        
   }
 
   public void onMessage(Message message) {
   }
}
  • LibraryMessageBean é anotado com a anotação @MessageDriven para marcá-lo como bean acionado por mensagem.

  • Suas propriedades são definidas como destinationType - Fila e destino - / queue / BookQueue.

  • Ele implementa a interface MessageListener, que expõe o método onMessage.

  • Possui MessgeDrivenContext como recurso.

  • O bean sem estado LibraryPersistentBeanRemote é injetado neste bean para fins de persistência.

Construa o projeto EjbComponent e implante-o no JBoss. Depois de construir e implantar o módulo EJB, precisamos de um cliente para enviar uma mensagem para a fila jboss.

Aplicação de exemplo

Vamos criar um aplicativo de teste EJB para testar o Message Driven Bean.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo . Você também pode usar o projeto criado no capítulo EJB - Criar Aplicativo como tal para este capítulo para entender os conceitos de persistência EJB.

2

Crie Book.java no pacote com.tutorialspoint.entity conforme criado no capítulo EJB-Persistence .

3

Crie LibraryPersistentBean.java e LibraryPersistentBeanRemote conforme criado no capítulo EJB-Persistence .

4

Crie jboss-ds.xml emEjbComponent > setup pasta e persistence.xml emEjbComponent > src > conf pasta. Essas pastas podem ser vistas na guia de arquivos no Netbeans, conforme criado no capítulo EJB-Persistência .

5

Crie LibraryMessageBean.java sob um pacote com.tutorialspoint.messagebean e modifique-o conforme mostrado abaixo.

6

Crie a fila BookQueue no Jboss conforme descrito acima.

7

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

8

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

9

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB. Modifique-o conforme mostrado abaixo.

EJBComponent (Módulo EJB)

LibraryMessageBean.java

package com.tutorialspoint.messagebean;
 
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
 
@MessageDriven(
   name = "BookMessageHandler",
   activationConfig = {
      @ActivationConfigProperty( propertyName = "destinationType", 
                                 propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty( propertyName = "destination", 
                                 propertyValue ="/queue/BookQueue")
   }
)
public class LibraryMessageBean implements MessageListener {
 
   @Resource
   private MessageDrivenContext mdctx;  
 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
 
   public LibraryMessageBean() {        
   }
 
   public void onMessage(Message message) {
      ObjectMessage objectMessage = null;
      try {
         objectMessage = (ObjectMessage) message;
         Book book = (Book) objectMessage.getObject(); 
         libraryBean.addBook(book);
 
      } catch (JMSException ex) {
         mdctx.setRollbackOnly();
      }       
   }   
}

Testador EJB (Cliente EJB)

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testMessageBeanEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testMessageBeanEjb() {
 
      try {
         int choice = 1; 
         Queue queue = (Queue) ctx.lookup("/queue/BookQueue");
         QueueConnectionFactory factory =
         (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
         QueueConnection connection =  factory.createQueueConnection();
         QueueSession session = 
         connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
         QueueSender sender = session.createSender(queue);
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               ObjectMessage objectMessage = 
                  session.createObjectMessage(book);
               sender.send(objectMessage); 
            } else if (choice == 2) {
               break;
            }
         }
 
         LibraryPersistentBeanRemote libraryBean = 
         (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }   
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testStatefulEjb (), a pesquisa do jndi é feita com o nome - "/ queue / BookQueue" para obter a referência da fila disponível no Jboss. Em seguida, o remetente é criado usando a sessão de fila.

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir a opção.

  • Se o usuário digitar 1, o sistema solicitará o nome do livro e o remetente enviará o nome do livro para a fila. Quando o contêiner JBoss recebe essa mensagem na fila, ele chama o método onMessage do nosso bean controlado por mensagem. Nosso bean acionado por mensagem salva o livro usando o método addBook () do bean de sessão com preservação de estado. O Session Bean está mantendo o livro no banco de dados por meio da chamada EntityManager.

  • Se o usuário inserir 2, outra consulta jndi será feita com o nome - "LibraryStatefulSessionBean / remote" para obter o objeto de negócios remoto (EJB com estado) novamente e a listagem de livros é feita.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console Netbeans -

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn EJB
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
1. learn EJB
BUILD SUCCESSFUL (total time: 15 seconds)

A saída mostrada acima afirma que nosso bean acionado por Mensagem está recebendo a mensagem e armazenando o livro em armazenamento persistente e os livros são recuperados do banco de dados.

As anotações foram introduzidas no Java 5.0. O objetivo de ter anotações é anexar informações adicionais na classe ou metadados de uma classe em seu código-fonte. No EJB 3.0, as anotações são usadas para descrever metadados de configuração em classes EJB. Dessa forma, o EJB 3.0 elimina a necessidade de descrever os dados de configuração em arquivos XML de configuração.

O contêiner EJB usa a ferramenta do compilador para gerar os artefatos necessários como interfaces e descritores de implantação lendo essas anotações. A seguir está a lista de anotações comumente usadas.

Sr. Não Nome Descrição
1

javax.ejb.Stateless

Especifica que uma determinada classe EJB é um bean de sessão sem estado.

Attributes

  • name - Usado para especificar o nome do bean de sessão.

  • mappedName - Usado para especificar o nome JNDI do bean de sessão.

  • description - Usado para fornecer a descrição do bean de sessão.

2

javax.ejb.Stateful

Especifica que uma determinada classe EJB é um bean de sessão com preservação de estado.

Attributes

  • name - Usado para especificar o nome do bean de sessão.

  • mappedName - Usado para especificar o nome JNDI do bean de sessão.

  • description - Usado para fornecer a descrição do bean de sessão.

3

javax.ejb.MessageDrivenBean

Especifica que uma determinada classe EJB é um bean acionado por mensagem.

Attributes

  • name - Usado para especificar o nome do bean acionado por mensagem.

  • messageListenerInterface - Usado para especificar a interface do listener de mensagem para o bean acionado por mensagem.

  • activationConfig - Usado para especificar os detalhes de configuração do bean controlado por mensagem em um ambiente operacional do bean controlado por mensagem.

  • mappedName - Usado para especificar o nome JNDI do bean de sessão.

  • description - Usado para fornecer a descrição do bean de sessão.

4

javax.ejb.EJB

Usado para especificar ou injetar uma dependência como instância EJB em outro EJB.

Attributes

  • name - Usado para especificar o nome, que será usado para localizar o bean referenciado no ambiente.

  • beanInterface - Usado para especificar o tipo de interface do bean referenciado.

  • beanName - Usado para fornecer o nome do bean referenciado.

  • mappedName - Usado para especificar o nome JNDI do bean referenciado.

  • description - Usado para fornecer a descrição do bean referenciado.

5

javax.ejb.Local

Usado para especificar interface (s) local (is) de um bean de sessão. Essa interface local indica os métodos de negócios do bean de sessão (que pode ser sem estado ou com estado).

Essa interface é usada para expor os métodos de negócios aos clientes locais, que estão sendo executados na mesma implementação / aplicativo que o EJB.

Attributes

  • value - Usado para especificar a lista de interfaces locais como uma matriz de interfaces.

6

javax.ejb.Remote

Usado para especificar interface (s) remota (s) de um bean de sessão. Essa interface remota indica os métodos de negócios do bean de sessão (que pode ser sem estado ou com estado).

Essa interface é usada para expor os métodos de negócios para clientes remotos, que estão sendo executados em diferentes implementações / aplicativos como EJB.

Attributes

  • value - Usado para especificar a lista de interfaces remotas como uma matriz de interfaces.

7

javax.ejb.Activation ConfigProperty

Usado para especificar as propriedades necessárias para um bean acionado por mensagem. Por exemplo, ponto final, destino, seletor de mensagem etc.

Esta anotação é passada como um parâmetro para o atributo activationConfig da anotação javax.ejb.MessageDrivenBean.

Attributes

  • propertyName - nome da propriedade.

  • propertyValue - valor do imóvel.

8

javax.ejb.PostActivate

Usado para especificar o método de retorno de chamada do ciclo de vida EJB. Este método será chamado quando o contêiner EJB acabou de ativar / reativar a instância do bean.

Essa interface é usada para expor os métodos de negócios para clientes locais, que estão sendo executados na mesma implementação / aplicativo que o EJB.

Callback é um mecanismo pelo qual o ciclo de vida de um enterprise bean pode ser interceptado. A especificação EJB 3.0 especificou retornos de chamada para os quais os métodos do manipulador de retorno de chamada são criados. O contêiner EJB chama esses retornos de chamada. Podemos definir métodos de retorno de chamada na própria classe EJB ou em uma classe separada. O EJB 3.0 forneceu muitas anotações para callbacks.

A seguir está a lista de anotações de retorno de chamada para bean sem estado -

Anotação Descrição
@PostConstruct Chamado quando um bean é criado pela primeira vez.
@PreDestroy Chamado quando um bean é removido do pool de bean ou destruído.

A seguir está a lista de anotações de retorno de chamada para bean com estado -

Anotação Descrição
@PostConstruct Chamado quando um bean é criado pela primeira vez.
@PreDestroy Chamado quando um bean é removido do pool de bean ou destruído.
@PostActivate Chamado quando um bean é carregado para ser usado.
@PrePassivate Chamado quando um bean é colocado de volta no pool de bean.

A seguir está a lista de anotações de retorno de chamada para bean acionado por mensagem -

Anotação Descrição
@PostConstruct Chamado quando um bean é criado pela primeira vez.
@PreDestroy Chamado quando um bean é removido do pool de bean ou destruído.

A seguir está a lista de anotações de retorno de chamada para bean de entidade -

Anotação Descrição
@PrePersist Chamado quando uma entidade é criada no banco de dados.
@PostPersist Chamado depois que uma entidade é criada no banco de dados.
@PreRemove Chamado quando uma entidade é excluída do banco de dados.
@PostRemove Chamado depois que uma entidade é excluída do banco de dados.
@PreUpdate Chamado antes de uma entidade ser atualizada no banco de dados.
@PostLoad Chamado quando um registro é obtido do banco de dados e carregado na entidade.

Aplicação de exemplo

Vamos criar um aplicativo de teste EJB para testar vários retornos de chamada no EJB.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.stateless conforme explicado no capítulo EJB - Criar Aplicativo . Você também pode usar o projeto criado no capítulo EJB - Persistência como tal para este capítulo para adicionar vários callbacks ao EJB.

2

Crie LibrarySessionBean.java e LibrarySessionBeanRemote conforme explicado no capítulo EJB - Criar aplicativo . Mantenha o resto dos arquivos inalterados.

3

Use os Beans criados no capítulo EJB - Persistência . Adicione métodos de retorno de chamada conforme mostrado abaixo. Mantenha o resto dos arquivos inalterados.

4

Crie uma classe java BookCallbackListener no pacote com.tutorialspoint.callback . Esta classe irá demonstrar a separação dos métodos de retorno de chamada.

5

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

6

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

7

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

EJBComponent (Módulo EJB)

BookCallbackListener.java

package com.tutorialspoint.callback;

import javax.persistence.PrePersist;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;

import com.tutorialspoint.entity.Book;

public class BookCallbackListener {
    
   @PrePersist
   public void prePersist(Book book) {
      System.out.println("BookCallbackListener.prePersist:" 
         + "Book to be created with book id: "+book.getId());
   }

   @PostPersist
   public void postPersist(Object book) {
      System.out.println("BookCallbackListener.postPersist::"
         + "Book created with book id: "+((Book)book).getId());
   }

   @PreRemove
   public void preRemove(Book book) {
      System.out.println("BookCallbackListener.preRemove:"
         + " About to delete Book: " + book.getId());
   }

   @PostRemove
   public void postRemove(Book book) {
      System.out.println("BookCallbackListener.postRemove::"
         + " Deleted Book: " + book.getId());
   }

   @PreUpdate
   public void preUpdate(Book book) {
      System.out.println("BookCallbackListener.preUpdate::"
         + " About to update Book: " + book.getId());
   }

   @PostUpdate
   public void postUpdate(Book book) {
      System.out.println("BookCallbackListener.postUpdate::"
         + " Updated Book: " + book.getId());
   }

   @PostLoad
   public void postLoad(Book book) {
      System.out.println("BookCallbackListener.postLoad::"
         + " Loaded Book: " + book.getId());
   }
}

Book.java

package com.tutorialspoint.entity;
 
import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name="books")
public class Book implements Serializable{
    
   private int id;
   private String name;
 
   public Book() {        
   }
 
   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }
 
   public void setId(int id) {
      this.id = id;
   }
 
   public String getName() {
      return name;
   }
 
   public void setName(String name) {
      this.name = name;
   }    
}

LibraryStatefulSessionBean.java

package com.tutorialspoint.stateful;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Stateful;

@Stateful
public class LibraryStatefulSessionBean 
   implements LibraryStatefulSessionBeanRemote {
   List<String> bookShelf;    

   public LibraryStatefulSessionBean() {
      bookShelf = new ArrayList<String>();
   }

   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    

   public List<String> getBooks() {
      return bookShelf;
   }

   @PostConstruct
   public void postConstruct() {
      System.out.println("LibraryStatefulSessionBean.postConstruct::"
         + " bean created.");
   }

   @PreDestroy
   public void preDestroy() {
      System.out.println("LibraryStatefulSessionBean.preDestroy:"
         + " bean removed.");
   }

   @PostActivate
   public void postActivate() {
      System.out.println("LibraryStatefulSessionBean.postActivate:"
         + " bean activated.");
   }

   @PrePassivate
   public void prePassivate() {
      System.out.println("LibraryStatefulSessionBean.prePassivate:"
         + " bean passivated.");
   }    
}

LibraryStatefulSessionBeanRemote.java

package com.tutorialspoint.stateful;

import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryStatefulSessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean 
   implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {}

   @PersistenceContext(unitName="EntityEjbPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {     
      return entityManager.createQuery("From Book")
         .getResultList();
   }

   @PostConstruct
   public void postConstruct() {
      System.out.println("postConstruct:: LibraryPersistentBean session bean"
         + " created with entity Manager object: ");
   }

   @PreDestroy
   public void preDestroy() {
      System.out.println("preDestroy: LibraryPersistentBean session"
      + " bean is removed ");
   }
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryPersistentBean/remote.

  • Estaremos usando esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBeanRemote ejbName: LibraryPersistentBean
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibrarySessionBeanRemote;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.List;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEntityEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEntityEjb() {    
      try {
      int choice = 1; 

      LibraryPersistentBeanRemote libraryBean = 
      (LibraryPersistentBeanRemote)
      ctx.lookup("LibraryPersistentBean/remote");

      while (choice != 2) {
         String bookName;
         showGUI();
         String strChoice = brConsoleReader.readLine();
         choice = Integer.parseInt(strChoice);
         if (choice == 1) {
            System.out.print("Enter book name: ");
            bookName = brConsoleReader.readLine();
            Book book = new Book();
            book.setName(bookName);
            libraryBean.addBook(book);          
         } else if (choice == 2) {
            break;
         }
      }

      List<Book> booksList = libraryBean.getBooks();

      System.out.println("Book(s) entered so far: " + booksList.size());
      int i = 0;
      for (Book book:booksList) {
         System.out.println((i+1)+". " + book.getName());
         i++;
      }           

      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }    
   }    
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testStatelessEjb (), a consulta jndi é feita com o nome - "LibrarySessionBean / remote" para obter o objeto de negócios remoto (EJB sem estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está armazenando o livro no banco de dados.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão sem estado e sai.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 13 seconds)

Saída de log do servidor de aplicativos JBoss

Você pode encontrar as seguintes entradas de retorno de chamada no log do JBoss

14:08:34,293 INFO  [STDOUT] postConstruct:: LibraryPersistentBean session bean created with entity Manager object
...
16:39:09,484 INFO  [STDOUT] BookCallbackListener.prePersist:: Book to be created with book id: 0
16:39:09,531 INFO  [STDOUT] BookCallbackListener.postPersist:: Book created with book id: 1
16:39:09,900 INFO  [STDOUT] BookCallbackListener.postLoad:: Loaded Book: 1
...

O serviço de cronômetro é um mecanismo pelo qual o aplicativo programado pode ser criado. Por exemplo, geração de comprovante de salário no primeiro dia de cada mês. A especificação EJB 3.0 especificou a anotação @Timeout, que ajuda na programação do serviço EJB em um bean sem estado ou controlado por mensagem. O contêiner EJB chama o método, que é anotado por @Timeout.

EJB Timer Service é um serviço fornecido pelo contêiner EJB, que ajuda a criar um cronômetro e a agendar o retorno de chamada quando o cronômetro expira.

Passos para criar cronômetro

Injete SessionContext no bean usando a anotação @Resource -

@Stateless
public class TimerSessionBean {

   @Resource
   private SessionContext context;
   ...
}

Use o objeto SessionContext para obter TimerService e para criar um cronômetro. Passe o tempo em milissegundos e mensagem.

public void createTimer(long duration) {
   context.getTimerService().createTimer(duration, "Hello World!");
}

Passos para usar o cronômetro

Use a anotação @Timeout para um método. O tipo de retorno deve ser nulo e passar um parâmetro do tipo Timer. Estamos cancelando o cronômetro após a primeira execução, caso contrário, ele continuará em execução após os intervalos de correção.

@Timeout
public void timeOutHandler(Timer timer) {
   System.out.println("timeoutHandler : " + timer.getInfo());        
   timer.cancel();
}

Aplicação de exemplo

Vamos criar um aplicativo EJB de teste para testar o Serviço de Timer no EJB.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent em um pacote com.tutorialspoint.timer conforme explicado no capítulo EJB - Criar Aplicativo .

2

Crie TimerSessionBean.java e TimerSessionBeanRemote conforme explicado no capítulo EJB - Criar Aplicativo . Mantenha o resto dos arquivos inalterados.

3

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

4

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

5

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

EJBComponent (Módulo EJB)

TimerSessionBean.java

package com.tutorialspoint.timer;

import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Timer;
import javax.ejb.Stateless;
import javax.ejb.Timeout;

@Stateless
public class TimerSessionBean implements TimerSessionBeanRemote {

   @Resource
   private SessionContext context;

   public void createTimer(long duration) {
      context.getTimerService().createTimer(duration, "Hello World!");
   }

   @Timeout
   public void timeOutHandler(Timer timer) {
      System.out.println("timeoutHandler : " + timer.getInfo());        
      timer.cancel();
   }
}

TimerSessionBeanRemote.java

package com.tutorialspoint.timer;

import javax.ejb.Remote;

@Remote
public interface TimerSessionBeanRemote {
   public void createTimer(long milliseconds);
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - TimerSessionBean/remote.

  • Usaremos esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.timer.TimerSessionBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   TimerSessionBean/remote - EJB3.x Default Remote Business Interface
   TimerSessionBean/remote-com.tutorialspoint.timer.TimerSessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=TimerSessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.timer.TimerSessionBeanRemote ejbName: TimerSessionBean
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.TimerSessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testTimerService();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testTimerService() {
      try {
         TimerSessionBeanRemote timerServiceBean = (TimerSessionBeanRemote)ctx.lookup("TimerSessionBean/remote");

         System.out.println("["+(new Date()).toString()+ "]" + "timer created.");
         timerServiceBean.createTimer(2000);            

      } catch (NamingException ex) {
         ex.printStackTrace();
      }
   }
}

O EJBTester está executando as seguintes tarefas.

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testTimerService (), a pesquisa jndi é feita com o nome - "TimerSessionBean / remote" para obter o objeto de negócios remoto (EJB sem estado do cronômetro).

  • Em seguida, o createTimer é invocado passando 2.000 milissegundos como tempo de agendamento.

  • O contêiner EJB chama o método timeoutHandler após 2 segundos.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
[Wed Jun 19 11:35:47 IST 2013]timer created.
BUILD SUCCESSFUL (total time: 0 seconds)

Saída de log do servidor de aplicativos JBoss

Você pode encontrar as seguintes entradas de retorno de chamada no log do JBoss

...
11:35:49,555 INFO  [STDOUT] timeoutHandler : Hello World!
...

A especificação EJB 3.0 fornece anotações, que podem ser aplicadas em campos ou métodos setter para injetar dependências. O contêiner EJB usa o registro JNDI global para localizar a dependência. As anotações a seguir são usadas no EJB 3.0 para injeção de dependência.

  • @EJB - usado para injetar outra referência EJB.

  • @Resource - usado para injetar fonte de dados ou serviços singleton como sessionContext, timerService etc.

Passos para usar @EJB

@EJB pode ser usado em campos ou métodos da seguinte maneira -

public class LibraryMessageBean implements MessageListener {
   //dependency injection on field. 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
   ...
}
public class LibraryMessageBean implements MessageListener {
  
   LibraryPersistentBeanRemote libraryBean;
   
   //dependency injection on method. 
   @EJB(beanName="com.tutorialspoint.stateless.LibraryPersistentBean")
   public void setLibraryPersistentBean(
   LibraryPersistentBeanRemote libraryBean)
   {
      this.libraryBean = libraryBean;
   }
   ...
}

Passos para usar @Resource

@Resource é normalmente usado para injetar singletons fornecidos pelo Contêiner EJB.

public class LibraryMessageBean implements MessageListener {
   @Resource
   private MessageDrivenContext mdctx;  
   ...
}

Aplicação de exemplo

Vamos criar um aplicativo EJB de teste para testar o Serviço de injeção de dependência no EJB.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent em um pacote com.tutorialspoint.timer conforme explicado no capítulo EJB - Criar Aplicativo .

2

Use Beans criados no capítulo EJB - Message Driven Bean . Mantenha o resto dos arquivos inalterados.

3

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

4

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

5

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

EJBComponent (Módulo EJB)

LibraryMessageBean.java

package com.tuturialspoint.messagebean;
 
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
 
@MessageDriven(
   name = "BookMessageHandler",
   activationConfig = {
      @ActivationConfigProperty( propertyName = "destinationType", 
                                 propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty( propertyName = "destination", 
                                 propertyValue ="/queue/BookQueue")
   }
)
public class LibraryMessageBean implements MessageListener {
 
   @Resource
   private MessageDrivenContext mdctx;  
 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
 
   public LibraryMessageBean() {        
   }
 
   public void onMessage(Message message) {
      ObjectMessage objectMessage = null;
      try {
         objectMessage = (ObjectMessage) message;
         Book book = (Book) objectMessage.getObject(); 
         libraryBean.addBook(book);
 
      }catch (JMSException ex) {
         mdctx.setRollbackOnly();
      }       
   }   
}

Testador EJB (Cliente EJB)

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testMessageBeanEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testMessageBeanEjb() {
 
      try {
         int choice = 1; 
         Queue queue = (Queue) ctx.lookup("/queue/BookQueue");
         QueueConnectionFactory factory =
         (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
         QueueConnection connection =  factory.createQueueConnection();
         QueueSession session = connection.createQueueSession( 
         false, QueueSession.AUTO_ACKNOWLEDGE);
         QueueSender sender = session.createSender(queue);
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               ObjectMessage objectMessage = 
               session.createObjectMessage(book);
               sender.send(objectMessage); 
            } else if (choice == 2) {
               break;
            }
         }
 
         LibraryPersistentBeanRemote libraryBean = 
         (LibraryPersistentBeanRemote)
		 ctx.lookup("LibraryPersistentBean/remote");
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " 
         + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }   
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testStatefulEjb (), a pesquisa jndi é feita com o nome - "/ queue / BookQueue" para obter a referência da fila disponível no Jboss. Em seguida, o remetente é criado usando a sessão de fila.

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário digitar 1, o sistema solicitará o nome do livro e o remetente enviará o nome do livro para a fila. Quando o contêiner JBoss recebe essa mensagem na fila, ele chama o método onMessage do nosso bean controlado por mensagem. Nosso bean acionado por mensagem salva o livro usando o método addBook () do bean de sessão com preservação de estado. O Session Bean está mantendo o livro no banco de dados por meio da chamada EntityManager.

  • Se o usuário inserir 2, outra consulta jndi será feita com o nome - "LibraryStatefulSessionBean / remote" para obter o objeto de negócios remoto (EJB com estado) novamente e a listagem de livros é feita.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn EJB
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
1. learn EJB
BUILD SUCCESSFUL (total time: 15 seconds)

A saída mostrada acima afirma que nosso bean acionado por mensagem está recebendo a mensagem e armazenando o livro em armazenamento persistente e os livros são recuperados do banco de dados.

Nosso bean controlado por mensagem está usando LibraryPersistentBean injetado nele usando a anotação @EJB e, em caso de exceção, MessageDrivenContext, o objeto é usado para reverter a transação.

O EJB 3.0 fornece especificações para interceptar chamadas de métodos de negócios usando métodos anotados com a anotação @AroundInvoke. Um método interceptor é chamado por ejbContainer antes da chamada do método de negócios estar interceptando. A seguir está o exemplo de assinatura de um método de interceptador

@AroundInvoke
public Object methodInterceptor(InvocationContext ctx) throws Exception {
   System.out.println("*** Intercepting call to LibraryBean method: " 
   + ctx.getMethod().getName());
   return ctx.proceed();
}

Os métodos do interceptor podem ser aplicados ou limitados em três níveis.

  • Default - O interceptor padrão é chamado para cada bean dentro da implantação. O interceptor padrão pode ser aplicado apenas via xml (ejb-jar.xml).

  • Class- O interceptor de nível de classe é chamado para cada método do bean. O interceptor de nível de classe pode ser aplicado por anotação via xml (ejb-jar.xml).

  • Method- O interceptor de nível de método é chamado para um método específico do bean. O interceptor de nível de método pode ser aplicado por anotação de via xml (ejb-jar.xml).

Estamos discutindo o interceptor de nível de classe aqui.

Classe Interceptor

package com.tutorialspoint.interceptor;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class BusinessInterceptor {
   @AroundInvoke
   public Object methodInterceptor(InvocationContext ctx) throws Exception {
      System.out.println("*** Intercepting call to LibraryBean method: " 
      + ctx.getMethod().getName());
      return ctx.proceed();
   }
}

Interface Remota

import javax.ejb.Remote;

@Remote
public interface LibraryBeanRemote {
   //add business method declarations
}

EJB sem estado interceptado

@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
   //implement business method 
}

Aplicação de exemplo

Vamos criar um aplicativo EJB de teste para testar o EJB sem estado interceptado.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent em um pacote com.tutorialspoint.interceptor conforme explicado no capítulo EJB - Criar Aplicativo . Você também pode usar o projeto criado no capítulo EJB - Criar Aplicativo como tal para este capítulo para entender os conceitos EJB interceptados.

2

Crie LibraryBean.java e LibraryBeanRemote no pacote com.tutorialspoint.interceptor conforme explicado no capítulo EJB - Criar aplicativo . Mantenha o resto dos arquivos inalterados.

3

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

4

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

5

Agora crie o cliente ejb, um aplicativo baseado em console da mesma maneira que explicado no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

EJBComponent (Módulo EJB)

LibraryBeanRemote.java

package com.tutorialspoint.interceptor;

import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibraryBean.java

package com.tutorialspoint.interceptor;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
    
   List<String> bookShelf;    

   public LibraryBean() {
      bookShelf = new ArrayList<String>();
   }

   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    

   public List<String> getBooks() {
      return bookShelf;
   }   
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryBean/remote.

  • Usaremos esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.interceptor.LibraryBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryBean/remote - EJB3.x Default Remote Business Interface
   LibraryBean/remote-com.tutorialspoint.interceptor.LibraryBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryBeanRemote ejbName: LibraryBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryBean/remote - EJB3.x Default Remote Business Interface
   LibraryBean/remote-com.tutorialspoint.interceptor.LibraryBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryBeanRemote;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.List;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testInterceptedEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testInterceptedEjb() {

      try {
         int choice = 1; 

         LibraryBeanRemote libraryBean =
         LibraryBeanRemote)ctx.lookup("LibraryBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }                
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testInterceptedEjb (), a pesquisa jndi é feita com o nome - "LibraryBean / remote" para obter o objeto de negócios remoto (EJB sem estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está armazenando o livro em sua variável de instância.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão sem estado e sai.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 13 seconds)

Saída de log do servidor de aplicativos JBoss

Verifique a seguinte saída na saída de log do servidor de aplicativos JBoss.

....
09:55:40,741 INFO  [STDOUT] *** Intercepting call to LibraryBean method: addBook
09:55:43,661 INFO  [STDOUT] *** Intercepting call to LibraryBean method: getBooks

O EJB 3.0 oferece a opção de incorporar JAVA POJO (Plain Old Java Object) em um bean de entidade e permite mapear nomes de coluna com os métodos da classe POJO incorporada. Um POJO java a ser incorporado deve ser anotado como @Embeddable.

@Embeddable
public class Publisher implements Serializable{
   private String name;
   private String address;
   ...
}

A classe acima pode ser incorporada usando a anotação @Embedded.

@Entity
public class Book implements Serializable{
   private int id;
   private String name;
   private Publisher publisher;
   ...
   @Embedded
   @AttributeOverrides({
      @AttributeOverride(name = "name", 
                      column = @Column(name = "PUBLISHER")),
      @AttributeOverride(name = "address", 
                      column = @Column(name = "PUBLISHER_ADDRESS"))
   })
   public Publisher getPublisher() {
      return publisher;
   }
   ...
}

Aplicação de exemplo

Vamos criar um aplicativo de teste EJB para testar objetos incorporados no EJB 3.0.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo . Use o projeto criado no capítulo EJB - Persistência como tal para este capítulo para entender os objetos incorporados nos conceitos EJB.

2

Crie Publisher.java no pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar aplicativo . Mantenha o resto dos arquivos inalterados.

3

Crie Book.java no pacote com.tutorialspoint.entity . Use o capítulo EJB - Persistência como referência. Mantenha o resto dos arquivos inalterados.

4

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

5

Finalmente, implante o aplicativo na forma de um arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

6

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

Criar / alterar tabela de livro

CREATE TABLE book (
   id     integer PRIMARY KEY,
   name   varchar(50)
);
Alter table book add publisher varchar(100);
Alter table book add publisher_address varchar(200);

EJBComponent (Módulo EJB)

Publisher.java

package com.tutorialspoint.entity;

import java.io.Serializable;
import javax.persistence.Embeddable;

@Embeddable
public class Publisher implements Serializable{
    
   private String name;
   private String address;

   public Publisher() {}

   public Publisher(String name, String address) {
      this.name = name;
      this.address = address;
   }

   public String getName() {
      return name;
   }

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

   public String getAddress() {
      return address;
   }

   public void setAddress(String address) {
      this.address = address;
   }

   public String toString() {
      return name + "," + address;
   }    
}

Book.java

package com.tutorialspoint.entity;

import com.tutorialspoint.callback.BookCallbackListener;
import java.io.Serializable;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="book")
public class Book implements Serializable{

   private int id;
   private String name;
   private Publisher publisher;

   public Book() {        
   }

   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

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


   @Embedded
   @AttributeOverrides({
      @AttributeOverride(name = "name", 
         column = @Column(name = "PUBLISHER")),
      @AttributeOverride(name = "address", 
         column = @Column(name = "PUBLISHER_ADDRESS"))
   })
   public Publisher getPublisher() {
      return publisher;
   }

   public void setPublisher(Publisher publisher) {
      this.publisher = publisher;
   }    
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryPersistentBean/remote.

  • Estaremos usando esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryBeanRemote;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.List;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEmbeddedObjects();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEmbeddedObjects() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean = 
        (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            String publisherName;
            String publisherAddress;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               System.out.print("Enter publisher name: ");
               publisherName = brConsoleReader.readLine();
               System.out.print("Enter publisher address: ");
               publisherAddress = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               book.setPublisher
              (new Publisher(publisherName,publisherAddress));

               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            System.out.println("Publication: "+book.getPublisher());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testInterceptedEjb (), a pesquisa jndi é feita com o nome - "LibraryPersistenceBean / remote" para obter o objeto de negócios remoto (EJB sem estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está armazenando o livro no banco de dados.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão sem estado e sai.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: learn html5
Enter publisher name: SAMS
Enter publisher address: DELHI
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn html5
Publication: SAMS,DELHI
BUILD SUCCESSFUL (total time: 21 seconds)

O EJB 3.0 fornece suporte para os tipos Blob e Clob usando a anotação @Lob. Os seguintes tipos de java podem ser mapeados usando a anotação @Lob.

  • java.sql.Blob
  • java.sql.Clob
  • byte[]
  • String
  • Objeto serializável
@Entity
@Table(name="books")
@EntityListeners(BookCallbackListener.class)
public class Book implements Serializable{
   ...
   private byte[] image;    

   @Lob @Basic(fetch= FetchType.EAGER)
   public byte[] getImage() {
      return image;
   }
   ...
}

Aplicação de exemplo

Vamos criar um aplicativo de teste EJB para testar o suporte a blob / clob no EJB 3.0.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo . Use o projeto criado no capítulo EJB - Persistência como tal para este capítulo para entender objetos clob / blob em conceitos ejb.

2

Crie Book.java no pacote com.tutorialspoint.entity . Use o capítulo EJB - Persistência como referência. Mantenha o resto dos arquivos inalterados.

3

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

4

Finalmente, implante o aplicativo na forma de um arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

5

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

Criar / alterar tabela de livro

CREATE TABLE book (
   id     integer PRIMARY KEY,
   name   varchar(50)
);
Alter table book add image bytea;
Alter table book add xml text;

EJBComponent (Módulo EJB)

Book.java

package com.tutorialspoint.entity;

import com.tutorialspoint.callback.BookCallbackListener;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;

@Entity
@Table(name="book")
public class Book implements Serializable{
    
   private int id;
   private String name;    
   private byte[] image;   
   private String xml;

   public Book() {        
   }

   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

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

   @Lob @Basic(fetch= FetchType.EAGER)
   public byte[] getImage() {
      return image;
   }

   public void setImage(byte[] image) {
      this.image = image;
   }

   @Lob @Basic(fetch= FetchType.EAGER)
   public String getXml() {
      return xml;
   }

   public void setXml(String xml) {
      this.xml = xml;
   }
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryPersistentBean/remote.

  • Usaremos esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testBlobClob();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testBlobClob() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean = 
        (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            String publisherName;
            String publisherAddress;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               String xml = "<book><name>"+bookName+"</name></book>";
               Book book = new Book();
               book.setName(bookName);                                        
               byte[] imageBytes = {0x32, 0x32,0x32, 0x32,0x32,
               0x32,0x32, 0x32,
               0x32, 0x32,0x32, 0x32,0x32, 0x32,0x32, 0x32,
               0x32, 0x32,0x32, 0x32,0x32, 0x32,0x32, 0x32
               };
               book.setImage(imageBytes);
               book.setXml(xml);

               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            byte[] imageByts = book.getImage();
            if(imageByts != null) {
               System.out.print("image bytes: [");
               for(int j = 0; j < imageByts.length ; j++) {
                  System.out.print("0x" 
                  + String.format("%x", imageByts[j]) +" ");
               }            
               System.out.println("]");
            }        
            System.out.println(book.getXml());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas.

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testInterceptedEjb (), a consulta jndi é feita com o nome - "LibraryPersistenceBean / remote" para obter o objeto de negócios remoto (EJB sem estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está armazenando o livro no banco de dados.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão sem estado e sai.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: learn testing
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn testing
image bytes: [
   0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 ]
<book><name>learn testing</name></book>
BUILD SUCCESSFUL (total time: 20 seconds)

Uma transação é uma unidade única de itens de trabalho, que segue as propriedades ACID. ACID significa Atômico, Consistente, Isolado e Durável.

  • Atomic- Se algum item de trabalho falhar, toda a unidade será considerada com falha. Sucesso significa que todos os itens são executados com sucesso.

  • Consistent - Uma transação deve manter o sistema em um estado consistente.

  • Isolated - Cada transação é executada independentemente de qualquer outra transação.

  • Durable - A transação deve sobreviver à falha do sistema se tiver sido executada ou confirmada.

Os contêineres / servidores EJB são servidores de transações e tratam da propagação do contexto das transações e das transações distribuídas. As transações podem ser gerenciadas pelo contêiner ou por manipulação de código customizado no código do bean.

  • Container Managed Transactions - Nesse tipo, o contêiner gerencia os estados da transação.

  • Bean Managed Transactions - Nesse tipo, o desenvolvedor gerencia o ciclo de vida dos estados da transação.

Transações gerenciadas por contêiner

EJB 3.0 especificou os seguintes atributos de transações, que os contêineres EJB implementam -

  • REQUIRED - Indica que o método de negócio deve ser executado dentro da transação, caso contrário, uma nova transação será iniciada para aquele método.

  • REQUIRES_NEW - Indica que uma nova transação deve ser iniciada para o método de negócio.

  • SUPPORTS - Indica que o método de negócios será executado como parte da transação.

  • NOT_SUPPORTED - Indica que o método de negócios não deve ser executado como parte da transação.

  • MANDATORY - Indica que o método de negócios será executado como parte da transação, caso contrário, uma exceção será lançada.

  • NEVER - Indica se o método de negócios é executado como parte da transação, então uma exceção será lançada.

Exemplo

package com.tutorialspoint.txn.required;
 
import javax.ejb.*
 
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserDetailBean implements UserDetailRemote {
	
   private UserDetail;

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public void createUserDetail() {
      //create user details object
   }
}

O método de negócios createUserDetail () torna-se Obrigatório usando a anotação Obrigatória.

package com.tutorialspoint.txn.required;
 
import javax.ejb.*
 
@Stateless
public class UserSessionBean implements UserRemote {
	
   private User;

   @EJB
   private UserDetailRemote userDetail;

   public void createUser() {
      //create user 
      //...
      //create user details
      userDetail.createUserDetail();
   }
}

O método de negócios createUser () está usando createUserDetail (). Se ocorrer uma exceção durante a chamada de createUser () e o objeto User não for criado, o objeto UserDetail também não será criado.

Bean Managed Transactions

Em Bean Managed Transactions, as transações podem ser gerenciadas manipulando exceções no nível do aplicativo.

A seguir estão os pontos-chave a serem considerados -

  • Start - Quando iniciar uma transação em um método de negócios.

  • Sucess - Identifique o cenário de sucesso quando uma transação deve ser confirmada.

  • Failed - Identifique o cenário de falha quando uma transação deve ser revertida.

Exemplo

package com.tutorialspoint.txn.bmt;
 
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;
 
@Stateless
@TransactionManagement(value=TransactionManagementType.BEAN)
public class AccountBean implements AccountBeanLocal {
 
   @Resource
   private UserTransaction userTransaction;

   public void transferFund(Account fromAccount, double fund , 
      Account toAccount) throws Exception{

      try{
         userTransaction.begin();

         confirmAccountDetail(fromAccount);
         withdrawAmount(fromAccount,fund);

         confirmAccountDetail(toAccount);
         depositAmount(toAccount,fund);

         userTransaction.commit();
      }catch (InvalidAccountException exception) {
         userTransaction.rollback();
      }catch (InsufficientFundException exception) {
         userTransaction.rollback();
      }catch (PaymentException exception) {
         userTransaction.rollback();
      }
   }

   private void confirmAccountDetail(Account account) 
      throws InvalidAccountException {
   }

   private void withdrawAmount() throws InsufficientFundException {
   }

   private void depositAmount() throws PaymentException{
   }
}

Neste exemplo, usamos UserTransaction interface para marcar o início da transação usando userTransaction.begin()chamada de método. Marcamos a conclusão da transação, usandouserTransaction.commit() método e se qualquer exceção ocorreu durante a transação, então, reverteremos a transação completa usando userTransaction.rollback() chamada de método.

A segurança é uma grande preocupação de qualquer aplicativo de nível empresarial. Inclui a identificação do (s) usuário (s) ou sistema que acessa o aplicativo. Com base na identificação, permite ou nega o acesso a recursos dentro da aplicação. Um contêiner EJB gerencia questões de segurança padrão ou pode ser personalizado para lidar com questões de segurança específicas.

Termos de segurança importantes

  • Authentication - Este é o processo que garante que o usuário que acessa o sistema ou aplicativo seja verificado para ser autêntico.

  • Authorization - Este é o processo que garante que o usuário autêntico tenha o nível correto de autoridade para acessar os recursos do sistema.

  • User - O usuário representa o cliente ou sistema que acessa o aplicativo.

  • User Groups - Os usuários podem fazer parte do grupo com certas autoridades, por exemplo, o grupo do administrador.

  • User Roles - As funções definem o nível de autoridade que um usuário possui ou permissões para acessar um recurso do sistema.

Segurança gerenciada por contêiner

O EJB 3.0 especificou os seguintes atributos / anotações de segurança, que os contêineres EJB implementam.

  • DeclareRoles- Indica que a classe aceitará as funções declaradas. As anotações são aplicadas no nível da classe.

  • RolesAllowed- Indica que um método pode ser acessado pelo usuário da função especificada. Pode ser aplicado no nível da classe, resultando em que todos os métodos da classe podem ser acessados ​​pelo usuário da função especificada.

  • PermitAll- Indica que um método de negócio está acessível a todos. Pode ser aplicado tanto em sala de aula quanto em nível de método.

  • DenyAll - Indica que um método de negócios não está acessível a nenhum usuário especificado na classe ou no nível do método.

Exemplo

package com.tutorialspoint.security.required;
 
import javax.ejb.*
 
@Stateless
@DeclareRoles({"student" "librarian"})
public class LibraryBean implements LibraryRemote {

   @RolesAllowed({"librarian"})
   public void delete(Book book) {
	  //delete book
   }
   
   @PermitAll
   public void viewBook(Book book) {
      //view book
   }
   
   @DenyAll
   public void deleteAll() {
      //delete all books
   } 
}

Configuração de Segurança

Mapeie funções e grupos de usuários no arquivo de configuração.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<ejb-jar>
   <security-role-mapping>
      <role-name>student</role-name>
      <group-name>student-group</group-name>
   </security-role-mapping>
   <security-role-mapping>
      <role-name>librarian</role-name>
      <group-name>librarian-group</group-name>
   </security-role-mapping>  
   <enterprise-beans/>
</ejb-jar>

JNDI significa Java Naming and Directory Interface. É um conjunto de API e interfaces de serviço. Os aplicativos baseados em Java usam JNDI para serviços de nomenclatura e diretório. No contexto do EJB, existem dois termos.

  • Binding - Refere-se à atribuição de um nome a um objeto EJB, que pode ser usado posteriormente.

  • Lookup - Refere-se a procurar e obter um objeto de EJB.

No Jboss, os beans de sessão são vinculados ao JNDI no seguinte formato por padrão.

  • local - nome EJB / local

  • remote - nome EJB / remoto

No caso, os EJB são agrupados com o arquivo <application-name> .ear, então o formato padrão é o seguinte -

  • local - nome do aplicativo / nome ejb / local

  • remote - nome do aplicativo / nome ejb / remoto

Exemplo de vinculação padrão

Consulte a saída do console JBoss do capítulo EJB - Criar aplicativo .

Saída de log do servidor de aplicativos JBoss

...
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
...

Encadernação Personalizada

As anotações a seguir podem ser usadas para personalizar as ligações JNDI padrão -

  • local - org.jboss.ejb3.LocalBinding

  • remote - org.jboss.ejb3.RemoteBindings

Atualize LibrarySessionBean.java. Consulte o capítulo EJB - Criar aplicativo .

LibrarySessionBean

package com.tutorialspoint.stateless;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
 
@Stateless
@LocalBinding(jndiBinding="tutorialsPoint/librarySession")
public class LibrarySessionBean implements LibrarySessionBeanLocal {
    
    List<String> bookShelf;    
    
    public LibrarySessionBean() {
       bookShelf = new ArrayList<String>();
    }
    
    public void addBook(String bookName) {
       bookShelf.add(bookName);
    }    
 
    public List<String> getBooks() {
        return bookShelf;
    }
}

LibrarySessionBeanLocal

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Local;
 
@Local
public interface LibrarySessionBeanLocal {
 
    void addBook(String bookName);
 
    List getBooks();
    
}

Construir o projeto, implantar o aplicativo no Jboss e verificar a seguinte saída no console do Jboss -

...
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   tutorialsPoint/librarySession - EJB3.x Default Local Business Interface
   tutorialsPoint/librarySession-com.tutorialspoint.stateless.LibrarySessionBeanLocal - EJB3.x Local Business Interface
...

O EJB 3.0 oferece a opção de definir relacionamentos / mapeamentos de entidade de banco de dados como relacionamentos um-para-um, um-para-muitos, muitos para um e muitos para muitos.

A seguir estão as anotações relevantes -

  • One-to-One- Os objetos têm relacionamento um-para-um. Por exemplo, um passageiro pode viajar usando um único bilhete de cada vez.

  • One-to-Many- Os objetos têm relacionamento um-para-muitos. Por exemplo, um pai pode ter vários filhos.

  • Many-to-One- Os objetos têm relacionamento muitos para um. Por exemplo, vários filhos com uma mãe solteira.

  • Many-to-Many- Os objetos têm relacionamento muitos para muitos. Por exemplo, um livro pode ter vários autores e um autor pode escrever vários livros.

Demonstraremos o uso do mapeamento ManyToMany aqui. Para representar o relacionamento ManyToMany, três tabelas a seguir são necessárias -

  • Book - Tabela de livros, contendo registros de livros.

  • Author - Tabela de autoria, contendo registros do autor.

  • Book_Author - Tabela de Autor do Livro, tendo vinculação da tabela Livro e Autor acima citada.

Criar tabelas

Crie uma mesa book author, book_author no banco de dados padrão postgres.

CREATE TABLE book (
   book_id     integer,   
   name   varchar(50)      
);

CREATE TABLE author (
   author_id   integer,
   name   varchar(50)      
);

CREATE TABLE book_author (
   book_id     integer,
   author_id   integer 
);

Criar classes de entidade

@Entity
@Table(name="author")
public class Author implements Serializable{
   private int id;
   private String name;
   ...   
}

@Entity
@Table(name="book")
public class Book implements Serializable{
   private int id;
   private String title;
   private Set<Author> authors;
   ...   
}

Use a anotação ManyToMany em Book Entity.

@Entity
public class Book implements Serializable{
   ...
   @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}
      , fetch = FetchType.EAGER)
   @JoinTable(table = @Table(name = "book_author"),
      joinColumns = {@JoinColumn(name = "book_id")},
      inverseJoinColumns = {@JoinColumn(name = "author_id")})
   public Set<Author> getAuthors() {
      return authors;
   }
   ...
}

Aplicação de exemplo

Vamos criar um aplicativo de teste EJB para testar objetos de relacionamento de entidades no EJB 3.0.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo . Use o projeto criado no capítulo EJB - Persistência como tal para este capítulo para entender os objetos incorporados nos conceitos EJB.

2

Crie Author.java no pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo . Mantenha o resto dos arquivos inalterados.

3

Crie Book.java no pacote com.tutorialspoint.entity . Use o capítulo EJB - Persistência como referência. Mantenha o resto dos arquivos inalterados.

4

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

5

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

6

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB.

EJBComponent (Módulo EJB)

Author.java

package com.tutorialspoint.entity;

import java.io.Serializable;

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

@Entity
@Table(name="author")
public class Author implements Serializable{
    
   private int id;
   private String name;

   public Author() {}

   public Author(int id, String name) {
      this.id = id;
      this.name = name;
   }
   
   @Id  
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="author_id")
   public int getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

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

   public String toString() {
      return id + "," + name;
   }    
}

Book.java

package com.tutorialspoint.entity;

import java.io.Serializable;

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

@Entity
@Table(name="book")
public class Book implements Serializable{

   private int id;
   private String name;
   private Set<Author> authors;

   public Book() {        
   }

   @Id  
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="book_id")
   public int getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

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

   public void setAuthors(Set<Author> authors) {
      this.authors = authors;
   }    
   
   @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}
      , fetch = FetchType.EAGER)
   @JoinTable(table = @Table(name = "book_author"),
      joinColumns = {@JoinColumn(name = "book_id")},
      inverseJoinColumns = {@JoinColumn(name = "author_id")})
   public Set<Author> getAuthors() {
      return authors;
   }
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryPersistentBean/remote.

  • Usaremos esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryBeanRemote;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.*;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEmbeddedObjects();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEmbeddedObjects() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean = 
         (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            String authorName;
            
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               System.out.print("Enter author name: ");
               authorName = brConsoleReader.readLine();               
               Book book = new Book();
               book.setName(bookName);
               Author author = new Author();
               author.setName(authorName);
               Set<Author> authors = new HashSet<Author>();
               authors.add(author);
               book.setAuthors(authors);

               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            System.out.print("Author: ");
            Author[] authors = (Author[])books.getAuthors().toArray();
            for(int j=0;j<authors.length;j++) {
               System.out.println(authors[j]);
            }
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testInterceptedEjb (), a consulta jndi é feita com o nome - "LibraryPersistenceBean / remote" para obter o objeto de negócios remoto (EJB sem estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está armazenando o livro no banco de dados.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão sem estado e sai.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: learn html5
Enter Author name: Robert
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn html5
Author: Robert
BUILD SUCCESSFUL (total time: 21 seconds)

No EJB 3.0, o mecanismo de persistência é usado para acessar o banco de dados no qual o contêiner gerencia as operações relacionadas ao banco de dados. Os desenvolvedores podem acessar o banco de dados usando a chamada da API JDBC diretamente nos métodos de negócios EJB.

Para demonstrar o acesso ao banco de dados em EJB, precisamos realizar as seguintes tarefas -

  • Step 1 - Crie uma tabela no banco de dados.

  • Step 2 - Crie um EJB sem estado para mim.

  • Step 3- Atualize o EJB sem estado. Adicione métodos para adicionar registros e obter registros do banco de dados por meio do gerenciador de entidades.

  • Step 4 - Um cliente de aplicativo baseado em console acessará o EJB sem estado para persistir os dados no banco de dados.

Criar a tabela

Crie uma mesa books no banco de dados padrão postgres.

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

Crie uma classe de modelo

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }
   ...
}

Criar EJB sem estado

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   public void addBook(Book book) {
     //persist book using jdbc calls
   }    

   public List<Book> getBooks() {        
     //get books using jdbc calls
   }
   ...
}

Depois de construir o módulo EJB, precisamos de um cliente para acessar o bean sem estado, que criaremos na próxima seção.

Aplicação de exemplo

Vamos criar um aplicativo EJB de teste para testar o mecanismo de acesso ao banco de dados EJB.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo . Você também pode usar o projeto criado no capítulo EJB - Criar Aplicativo como tal para este capítulo para entender os conceitos de acesso a dados EJB.

2

Crie Book.java no pacote com.tutorialspoint.entity e modifique-o conforme mostrado abaixo.

3

Crie LibraryPersistentBean.java e LibraryPersistentBeanRemote conforme explicado no capítulo EJB - Criar aplicativo e modifique-os conforme mostrado abaixo.

4

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

5

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

6

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB. Modifique-o conforme mostrado abaixo.

EJBComponent (Módulo EJB)

Book.java

package com.tutorialspoint.entity;

import java.io.Serializable;

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

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

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   public void addBook(Book book) {
      Connection con = null;
      String url = "jdbc:postgresql://localhost:5432/postgres";
      String driver = "org.postgresql.driver";

      String userName = "sa";
      String password = "sa";
      List<Book> books = new ArrayList<Book>();
      try {

         Class.forName(driver).newInstance();
         con = DriverManager.getConnection(url , userName, password);

         PreparedStatement st = 
         con.prepareStatement("insert into book(name) values(?)");
         st.setString(1,book.getName());

         int result = st.executeUpdate();                

      } catch (SQLException ex) {
         ex.printStackTrace();
      } catch (InstantiationException ex) {
         ex.printStackTrace();
      } catch (IllegalAccessException ex) {
         ex.printStackTrace();
      } catch (ClassNotFoundException ex) {
         ex.printStackTrace();
      }    
   }    

   public List<Book> getBooks() {
      Connection con = null;
      String url = "jdbc:postgresql://localhost:5432/postgres";
      String driver = "org.postgresql.driver";
   
      String userName = "sa";
      String password = "sa";
      List<Book> books = new ArrayList<Book>();
      try {

         Class.forName(driver).newInstance();
         con = DriverManager.getConnection(url , userName, password);

         Statement st = con.createStatement();
         ResultSet rs = st.executeQuery("select * from book");

         Book book;
         while (rs.next()) {
            book = new Book();
            book.setId(rs.getInt(1));                 
            book.setName(rs.getString(2));
            books.add(book);
         }
      } catch (SQLException ex) {
         ex.printStackTrace();
      } catch (InstantiationException ex) {
         ex.printStackTrace();
      } catch (IllegalAccessException ex) {
         ex.printStackTrace();
      } catch (ClassNotFoundException ex) {
         ex.printStackTrace();
      }
      return books;
   }
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryPersistentBean/remote.

  • Estaremos usando esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEntityEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEntityEjb() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean =
         LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testStatefulEjb (), a pesquisa jndi é feita com o nome - "LibraryStatelessSessionBean / remote" para obter o objeto de negócios remoto (EJB com estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está mantendo o livro no banco de dados por meio da chamada EntityManager.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão sem estado e sai.

  • Em seguida, outra pesquisa jndi é feita com o nome - "LibraryStatelessSessionBean / remote" para obter o objeto de negócios remoto (EJB com estado) novamente e a listagem de livros é feita.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn java
BUILD SUCCESSFUL (total time: 15 seconds)

EJB Query Languageé muito útil para escrever consultas personalizadas sem se preocupar com os detalhes do banco de dados subjacente. É bastante semelhante a HQL, linguagem de consulta de hibernação e costuma ser chamada de EJBQL.

Para demonstrar EJBQL em EJB, vamos fazer as seguintes tarefas -

  • Step 1 - Crie uma tabela no banco de dados.

  • Step 2 - Crie um EJB sem estado para mim.

  • Step 3−Atualizar EJB sem estado. Adicione métodos para adicionar registros e obter registros do banco de dados por meio do gerenciador de entidades.

  • Step 4 - Um cliente de aplicativo baseado em console acessará o EJB sem estado para persistir os dados no banco de dados.

Criar a tabela

Crie uma mesa books no banco de dados padrão postgres.

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

Crie uma classe de modelo

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }
   ...
}

Criar EJB sem estado

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   public void addBook(Book book) {
     //persist book using entity manager
   }    

   public List<Book> getBooks() {        
     //get books using entity manager
   }
   ...
}

Depois de construir o módulo EJB, precisamos de um cliente para acessar o bean sem estado, que criaremos na próxima seção.

Aplicação de exemplo

Vamos criar um aplicativo EJB de teste para testar o mecanismo de acesso ao banco de dados EJB.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo . Você também pode usar o projeto criado no capítulo EJB - Criar Aplicativo como tal para este capítulo para entender os conceitos de acesso a dados EJB.

2

Crie Book.java no pacote com.tutorialspoint.entity e modifique-o conforme mostrado abaixo.

3

Crie LibraryPersistentBean.java e LibraryPersistentBeanRemote conforme explicado no capítulo EJB - Criar aplicativo e modifique-os conforme mostrado abaixo.

4

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

5

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

6

Agora crie o cliente EJB, um aplicativo baseado em console da mesma maneira explicada no capítulo EJB - Criar Aplicativo no tópicoCreate Client to access EJB. Modifique-o conforme mostrado abaixo.

EJBComponent (Módulo EJB)

Book.java

package com.tutorialspoint.entity;

import java.io.Serializable;

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }

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

   public String getName() {
      return name;
   }

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

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {
   void addBook(Book bookName);
   List<Book> getBooks();
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EntityEjbPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      //create an ejbql expression
      String ejbQL = "From Book b where b.name like ?1";
      //create query
      Query query = entityManager.createQuery(ejbQL);
      //substitute parameter.
      query.setParameter(1, "%test%");   
      //execute the query
      return query.getResultList();
   }   
}
  • Assim que você implantar o projeto EjbComponent no JBOSS, observe o log do jboss.

  • JBoss criou automaticamente uma entrada JNDI para nosso bean de sessão - LibraryPersistentBean/remote.

  • Estaremos usando esta string de pesquisa para obter objeto de negócios remoto do tipo - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

Saída de log do servidor de aplicativos JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

Testador EJB (Cliente EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • Essas propriedades são usadas para inicializar o objeto InitialContext do serviço de nomenclatura java.

  • O objeto InitialContext será usado para pesquisar o bean de sessão sem estado.

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEntityEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEntityEjb() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean =
         LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

O EJBTester executa as seguintes tarefas -

  • Carregue as propriedades de jndi.properties e inicialize o objeto InitialContext.

  • No método testStatefulEjb (), a consulta jndi é feita com o nome - "LibraryStatelessSessionBean / remote" para obter o objeto de negócios remoto (ejb com estado).

  • Em seguida, o usuário vê uma interface do usuário da loja da biblioteca e ele / ela é solicitado a inserir uma escolha.

  • Se o usuário inserir 1, o sistema solicitará o nome do livro e salvará o livro usando o método addBook () do bean de sessão sem estado. O Session Bean está mantendo o livro no banco de dados por meio da chamada EntityManager.

  • Se o usuário inserir 2, o sistema recupera os livros usando o método getBooks () do bean de sessão sem estado e sai.

  • Em seguida, outra pesquisa jndi é feita com o nome - "LibraryStatelessSessionBean / remote" para obter o objeto de negócios remoto (EJB com estado) novamente e a listagem de livros é feita.

Execute o cliente para acessar o EJB

Localize EJBTester.java no explorador de projetos. Clique com o botão direito na classe EJBTester e selecionerun file.

Verifique a seguinte saída no console do Netbeans.

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Testing
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn Testing
BUILD SUCCESSFUL (total time: 15 seconds)

Os EJBs são parte de aplicativos corporativos que normalmente são baseados em ambientes distribuídos. Portanto, além das exceções normais que podem ocorrer, pode haver exceções como falha de comunicação, permissões de segurança, servidor inativo, etc.

O contêiner EJB considera as exceções de duas maneiras -

  • Application Exception - Se a regra de negócios for violada ou ocorrer uma exceção durante a execução da lógica de negócios.

  • System Exception- Qualquer exceção, que não seja causada pela lógica de negócios ou código de negócios. RuntimeException, RemoteException são SystemException. Por exemplo, erro durante a consulta EJB. RuntimeException, RemoteException são SystemException.

Como o contêiner EJB trata as exceções?

Quando Application Exceptionocorre, o contêiner EJB intercepta a exceção, mas retorna o mesmo para o cliente. Ele não reverte a transação, a menos que seja especificado no código pelo método EJBContext.setRollBackOnly (). O contêiner EJB não envolve a exceção no caso de exceção do aplicativo.

Quando System Exceptionocorrer, o contêiner EJB intercepta a exceção, reverte a transação e inicia as tarefas de limpeza. Ele envolve a exceção em RemoteException e a lança para o cliente.

Lidando com exceção de aplicativo

As exceções de aplicativo geralmente são lançadas em métodos EJB de sessão, pois esses são os métodos responsáveis ​​por executar a lógica de negócios. A exceção do aplicativo deve ser declarada na cláusula throws do método de negócios e deve ser lançada no caso de falha da lógica de negócios.

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   ...

   public List<Book> getBooks() throws NoBookAvailableException {        
      List<Book> books = 
         entityManager.createQuery("From Books").getResultList();
      if(books.size == 0)
		throw NoBookAvailableException
           ("No Book available in library.");
      return books;
   }
   ...
}

Lidando com exceção do sistema

A exceção do sistema pode ocorrer a qualquer momento, como a pesquisa de nomenclatura falha, o erro sql ocorre durante a busca de dados. Nesse caso, essa exceção deve ser agrupada em EJBException e devolvida ao cliente.

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   ...

   public List<Book> getBooks() {   
      try {
         List<Book> books = 
            entityManager.createQuery("From Books").getResultList();
      } catch (CreateException ce) {
         throw (EJBException) new EJBException(ce).initCause(ce);
      } catch (SqlException se) {
         throw (EJBException) new EJBException(se).initCause(se);    
      }	  
      return books;
   }
   ...
}

No lado do cliente, lide com a EJBException.

public class EJBTester {
   private void testEntityEjb() {
   ...
   try{
      LibraryPersistentBeanRemote libraryBean =
      LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");
   
      List<Book> booksList = libraryBean.getBooks();
   } catch(EJBException e) {
      Exception ne = (Exception) e.getCause();
      if(ne.getClass().getName().equals("SqlException")) {
         System.out.println("Database error: "+ e.getMessage());
      }
   }
   ...
   }
}

O EJB 3.0 fornece uma opção para expor o EJB da sessão como um serviço da web. A anotação @WebService é usada para marcar uma classe como um ponto final de serviço da web e @WebMethod é usada para expor um método como método da web para o cliente.

@Stateless
@WebService(serviceName="LibraryService")
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   ...
   @WebMethod(operationName="getBooks")
   public List<Book> getBooks()  {    
      return entityManager.createQuery("From Books").getResultList();
   }
   ...
}

Aplicação de exemplo

Vamos criar um aplicativo de teste EJB para testar o suporte a blob / clob no EJB 3.0.

Degrau Descrição
1

Crie um projeto com um nome EjbComponent sob um pacote com.tutorialspoint.entity conforme explicado no capítulo EJB - Criar Aplicativo. Use o projeto criado no capítulo EJB - Persistência como tal para este capítulo para entender objetos clob / blob em conceitos EJB.

2

Crie LibraryPersistentBean.java no pacote com.tutorialspoint.stateless. Use o capítulo EJB - Persistência como referência. Mantenha o resto dos arquivos inalterados.

3

Limpe e construa o aplicativo para garantir que a lógica de negócios esteja funcionando de acordo com os requisitos.

4

Finalmente, implante o aplicativo na forma de arquivo jar no JBoss Application Server. O servidor de aplicativos JBoss será iniciado automaticamente se ainda não tiver sido iniciado.

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
@WebService(serviceName="LibraryService")
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    
   
   @WebMethod(operationName="getBooks")
   public List <Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}

Saída de log do servidor de aplicativos JBoss

10:51:37,271 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBean ejbName: LibraryPersistentBean
10:51:37,287 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

	LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
	LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface

10:51:37,349 INFO  [EJBContainer] STARTED EJB: com.tuturialspoint.messagebean.LibraryMessageBean ejbName: BookMessageHandler
10:51:37,443 INFO  [DefaultEndpointRegistry] register: jboss.ws:context=EjbComponent,endpoint=LibraryPersistentBean
10:51:38,191 INFO  [WSDLFilePublisher] WSDL published to: file:/D:/Jboss-5.0.1/server/default/data/wsdl/EjbComponent.jar/
LibraryService3853081455302946642.wsdl

Crie o cliente para acessar o EJB como serviço da Web

No NetBeans IDE, selecione ,File > New Project >.Selecione o tipo de projeto na categoria,Java, Tipo de projeto como Java Application. CliqueNext >button.Insira o nome e a localização do projeto. CliqueFinish >botão. Escolhemos o nome como EJBWebServiceClient.

Clique com o botão direito no nome do projeto na janela Project explorer. SelecioneNew > WebService Client.

Adicionar LibraryPersistentBean do projeto de componente EJB criado anteriormente em WSDL e localização do cliente usando Add Project botão em compile aba.

Clique no botão Concluir. Verifique a estrutura a seguir no explorador de projetos.

Crie EJBWebServiceClient.java

package ejbwebserviceclient;

public class EJBWebServiceClient {
   public static void main(String[] args) {   
   }
}

Selecione o método da web getBooks do Web Service conforme mostrado na figura abaixo e arraste-o para a janela de código de EJBWebServiceClient.

Você verá uma saída semelhante à mostrada abaixo.

Atualize o código EJBWebServiceClient para usar este método.

package ejbwebserviceclient;

public class EJBWebServiceClient {

   public static void main(String[] args) {
      for(com.tutorialspoint.stateless.Book book:getBooks()) {
         System.out.println(book.getName());
      }       
   }

   private static java.util.List
   <com.tutorialspoint.stateless.Book> getBooks() {
      com.tutorialspoint.stateless.LibraryService service = 
         new com.tutorialspoint.stateless.LibraryService();
      com.tutorialspoint.stateless.LibraryPersistentBean port = 
         service.getLibraryPersistentBeanPort();
      return port.getBooks();
   }      
}

Execute o cliente

Clique com o botão direito no nome do projeto na janela Project explorer. SelecioneRun. O Netbeans irá construir o cliente e executá-lo. Verifique a seguinte saída.

ant -f D:\\SVN\\EJBWebServiceClient run
init:
Deleting: D:\SVN\EJBWebServiceClient\build\built-jar.properties
deps-jar:
Updating property file: D:\SVN\EJBWebServiceClient\build\built-jar.properties
wsimport-init:
wsimport-client-LibraryPersistentBean:
files are up to date
classLoader = java.net.URLClassLoader@4ce46c
SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@182cdac
wsimport-client-generate:
Compiling 1 source file to D:\SVN\EJBWebServiceClient\build\classes
compile:
run:
learn java
Learn Spring
learn JSF
Learn HTML
Learn JBoss
Learn EJB
Learn Hibernate
Learn IBatis
Times Now
learn html5
Learn images
Learn Testing
Forbes
test1
BUILD SUCCESSFUL (total time: 1 second)

Os requisitos de aplicativos de empacotamento usando EJB 3.0 são semelhantes aos da plataforma J2EE. Os componentes EJB são empacotados em módulos como arquivos jar e são empacotados em archive corporativo de aplicativo como arquivo ear.

Existem basicamente três componentes de qualquer aplicativo empresarial -

  • jar - Java Application aRchive, contendo módulos EJB, módulos cliente EJB e módulos utilitários.

  • war - Web Application aRchive, contendo módulos web.

  • ear - Enterprise Application aRchive, contendo jarros e módulo de guerra.

No NetBeans, é muito fácil criar, desenvolver, empacotar e implantar os aplicativos J2EE.

No NetBeans IDE, selecione,File > New Project >.Selecione o tipo de projeto na categoria,Java EE, Tipo de projeto como Enterprise Application. CliqueNext >botão. Insira o nome e o local do projeto. CliqueFinish >botão. Escolhemos o nome como EnterpriseApplicaton.

Selecione Servidor e configurações. ManterCreate EJB Module e Create Web Application Moduleverificado com os nomes padrão fornecidos. Clique no botão Concluir. O NetBeans criará a seguinte estrutura na janela do projeto.

Clique com o botão direito no Projeto Enterprise Application no explorador de projetos e selecione Construir.

ant -f D:\\SVN\\EnterpriseApplication dist
pre-init:
init-private:
init-userdir:
init-user:
init-project:
do-init:
post-init:
init-check:
init:
deps-jar:
deps-j2ee-archive:
EnterpriseApplication-ejb.init:
EnterpriseApplication-ejb.deps-jar:
EnterpriseApplication-ejb.compile:
EnterpriseApplication-ejb.library-inclusion-in-manifest:

Building jar: D:\SVN\EnterpriseApplication\EnterpriseApplication-ejb\dist\EnterpriseApplication-ejb.jar

EnterpriseApplication-ejb.dist-ear:
EnterpriseApplication-war.init:
EnterpriseApplication-war.deps-module-jar:
EnterpriseApplication-war.deps-ear-jar:
EnterpriseApplication-ejb.init:
EnterpriseApplication-ejb.deps-jar:
EnterpriseApplication-ejb.compile:
EnterpriseApplication-ejb.library-inclusion-in-manifest:
EnterpriseApplication-ejb.dist-ear:
EnterpriseApplication-war.deps-jar:
EnterpriseApplication-war.library-inclusion-in-archive:
EnterpriseApplication-war.library-inclusion-in-manifest:
EnterpriseApplication-war.compile:
EnterpriseApplication-war.compile-jsps:
EnterpriseApplication-war.do-ear-dist:

Building jar: D:\SVN\EnterpriseApplication\EnterpriseApplication-war\dist\EnterpriseApplication-war.war

EnterpriseApplication-war.dist-ear:
pre-pre-compile:
pre-compile:
Copying 1 file to D:\SVN\EnterpriseApplication\build
Copying 1 file to D:\SVN\EnterpriseApplication\build
do-compile:
post-compile:
compile:
pre-dist:
do-dist-without-manifest:
do-dist-with-manifest:

Building jar: D:\SVN\EnterpriseApplication\dist\EnterpriseApplication.ear

post-dist:
dist:
BUILD SUCCESSFUL (total time: 1 second)

Aqui você pode ver que o Netbeans prepara primeiro o Jar, depois o War e, no final, o arquivo ear carregando o jar e o war, file. Cada arquivo jar, war e ear carrega ummeta-inf pasta para ter metadados de acordo com a especificação J2EE.