EJB - Kalıcılık

EJB 3.0, EJB 2.0'da kullanılan varlık çekirdeği büyük ölçüde kalıcılık mekanizması ile değiştirilmiştir. Şimdi varlık çekirdeği, tablo ile eşleştirmeye sahip basit bir POJO'dur.

Kalıcılık API'sindeki temel aktörler şunlardır -

  • Entity- Veri deposu kaydını temsil eden kalıcı bir nesne. Serileştirilebilir olmak iyidir.

  • EntityManager- Kalıcı nesne (varlık) üzerinde ekleme / silme / güncelleme / bulma gibi veri işlemlerini yapmak için kalıcılık arayüzü. Ayrıca kullanarak sorgu yürütmeye yardımcı olurQuery arayüz.

  • Persistence unit (persistence.xml) - Kalıcılık birimi, kalıcılık mekanizmasının özelliklerini açıklar.

  • Data Source (*ds.xml)- Veri Kaynağı, bağlantı url'si gibi veri deposu ile ilgili özellikleri açıklar. kullanıcı adı, şifre vb.

EJB kalıcılık mekanizmasını göstermek için aşağıdaki görevleri yapmamız gerekir -

  • Step 1 - Veritabanında tablo oluşturun.

  • Step 2 - Tabloya karşılık gelen Varlık sınıfı oluşturun.

  • Step 3 - Veri Kaynağı ve Kalıcılık Birimi oluşturun.

  • Step 4 - EntityManager örneğine sahip durumsuz bir EJB oluşturun.

  • Step 5- Durum bilgisi olmayan EJB'yi güncelleyin. Varlık yöneticisi aracılığıyla kayıt eklemek ve veritabanından kayıt almak için yöntemler ekleyin.

  • Step 6 - Konsol tabanlı bir uygulama istemcisi, verileri veritabanında saklamak için durum bilgisiz EJB'ye erişecektir.

Tablo Oluştur

Tablo oluştur books varsayılan veritabanında postgres.

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

Varlık sınıfı oluştur

//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;
   }
   ...
}

DataSource ve Persistence Birimi Oluşturun

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>

Kalıcılık Birimi (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>

EntityManager Örneğine Sahip Durum Bilgisiz EJB Oluşturun

@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();
   }
   ...
}

EJB modülünü oluşturduktan sonra, bir sonraki bölümde oluşturacağımız durumsuz çekirdeğe erişmek için bir müşteriye ihtiyacımız var.

Örnek Uygulama

EJB kalıcılık mekanizmasını test etmek için bir test EJB uygulaması oluşturalım.

Adım Açıklama
1

EJB - Uygulama Oluştur bölümünde açıklandığı gibi com.tutorialspoint.entity paketinin altında EjbComponent adıyla bir proje oluşturun . EJB kalıcılık kavramlarını anlamak için, bu bölümde olduğu gibi EJB - Uygulama Oluştur bölümünde oluşturulan projeyi de kullanabilirsiniz .

2

Oluşturma Book.java paket altında com.tutorialspoint.entity ve aşağıda gösterildiği gibi değiştirebilirsiniz.

3

Oluşturma LibraryPersistentBean.java ve LibraryPersistentBeanRemote açıklandığı şekilde EJB - Uygulama oluşturma bölümleri ve aşağıda gösterildiği gibi bunları değiştirin.

4

Oluşturmak jboss-ds.xml içindeEjbComponent > setup klasör ve kalıcılık.xml içindeEjbComponent > src > conf Klasör. Bu klasörler Netbeans'deki dosyalar sekmesinde görülebilir. Bu dosyaları yukarıda gösterildiği gibi değiştirin.

5

İş mantığının gereksinimlere göre çalıştığından emin olmak için uygulamayı temizleyin ve oluşturun.

6

Son olarak, uygulamayı JBoss Uygulama Sunucusunda jar dosyası biçiminde dağıtın. Henüz başlatılmamışsa JBoss Uygulama sunucusu otomatik olarak başlayacaktır.

7

Şimdi, başlık altındaki EJB - Uygulama Oluştur bölümünde açıklandığı gibi, konsol tabanlı bir uygulama olan EJB istemcisini oluşturun.Create Client to access EJB. Aşağıda gösterildiği gibi değiştirin.

EJBComponent (EJB Modülü)

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();
   }
}
  • EjbComponent projesini JBOSS üzerinde dağıtır dağıtmaz, jboss günlüğüne dikkat edin.

  • JBoss, oturum fasulyemiz için otomatik olarak bir JNDI girişi oluşturdu - LibraryPersistentBean/remote.

  • Bu arama dizesini, türündeki uzak iş nesnesini elde etmek için kullanacağız - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

JBoss Uygulama Sunucusu Günlük Çıktısı

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

EJBTester (EJB İstemcisi)

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
  • Bu özellikler, java adlandırma hizmetinin InitialContext nesnesini başlatmak için kullanılır.

  • InitialContext nesnesi, durum bilgisiz oturum çekirdeğini aramak için kullanılacaktır.

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());
         }
      }
   }
}

EJBTester aşağıdaki görevleri gerçekleştirir.

  • Jndi.properties dosyasından özellikleri yükleyin ve InitialContext nesnesini başlatın.

  • TestStatefulEjb () yönteminde jndi araması, uzak iş nesnesini (durum bilgisi olan ejb) elde etmek için "LibraryStatefulSessionBean / remote" adıyla yapılır.

  • Ardından kullanıcıya bir kütüphane mağazası Kullanıcı Arayüzü gösterilir ve seçimini girmesi istenir.

  • Kullanıcı 1 girerse, sistem kitap adını sorar ve kitabı durum bilgisiz oturum fasulyesi addBook () yöntemini kullanarak kaydeder. Session Bean, EntityManager çağrısı ile kitabı veritabanında tutuyor.

  • Kullanıcı 2 girerse, sistem durum bilgisi olan oturum bean getBooks () yöntemini kullanarak kitapları alır ve çıkar.

  • Daha sonra, uzak iş nesnesini (durumsuz EJB) tekrar elde etmek için "LibraryStatelessSessionBean / remote" adıyla başka bir jndi araması yapılır ve kitapların listelenmesi yapılır.

EJB'ye Erişmek için İstemciyi Çalıştırın

Proje gezgininde EJBTester.java'yı bulun. EJBTester sınıfına sağ tıklayın ve seçinrun file.

Netbeans konsolunda aşağıdaki çıktıyı doğrulayın -

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'ye Erişmek İçin İstemciyi Yeniden Çalıştırın

EJB'ye erişmeden önce JBoss'u yeniden başlatın.

Proje gezgininde EJBTester.java'yı bulun. EJBTester sınıfına sağ tıklayın ve seçinrun file.

Netbeans konsolunda aşağıdaki çıktıyı doğrulayın.

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)

Yukarıda gösterilen çıktı, kitapların kalıcı depoda saklandığını ve veritabanından alındığını belirtir.

Önceki sayfa