EJB

EJB 9 -Embeddable Objects

Merhabalar arkadaşlar. Bu yazıda EJB mekanizması içindeki Embeddable Objects konusunu öğreneceğiz.

Embeddable Object Java sınıfına haritalanmış bir tablo içindeki bazı kolonların bir değişken ile yönetilebilmesidir. Yani kolonlar Entity sınıfı içersinde değil de yazılmış olan bir başka POJO vasıtası ile yönetilebilinir hale getiriliyor. Burada amaç benim anladığım kadarı ile kodun daha anlaşılır hale getirebilmesinin hedeflenmesidir.

Şimdi örnek uygulama ile nasıl yapıldığına bakalım ve konuyu daha iyi anlayalım. Bu uygulamayı Apache TomEE sunucusu kullanarak yaptım. Siz eğer GlassFish kullanıyorsanız @PersistenceContext kullanımı için şuradaki yazımdaki işlemleri tekrarlamanız gerekebilir. TomEE için o işlemler gerekmiyor ve direk kullanabiliyoruz.

Öncelikle size Java sınıfına haritalanacak tabloyu göstereyim.

Screen Shot 2015-12-05 at 19.06.55

Biz  bu tablo içindeki adres ve telephone alanlarını sınıfa doğrudan haritalayıp kullanmak yerine Accessing adındaki bir POJO ile yönetip kullanacağız.

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>EJB Embeddable Example</title>
    </h:head>
    <h:body>
        <center>
            <h:form>
                <h:panelGrid columns="2">
                    <h:outputText value="İsim:"/>
                    <h:inputText value="#{embeddableJSFBean.embdeddabletable.name}"/>

                    <h:outputText value="Soyisim:"/>
                    <h:inputText value="#{embeddableJSFBean.embdeddabletable.surname}"/>

                    <h:outputText value="Telefon"/>
                    <h:inputText value="#{embeddableJSFBean.accessing.telephone}"/>
                    
                    <h:outputText value="Adres"/>
                    <h:inputText value="#{embeddableJSFBean.accessing.address}"/>

                    <h:outputText value=""/>
                    <h:commandButton value="KAYDET" action="#{embeddableJSFBean.callEJBMethod}"/>

                    <h:outputText value=""/>
                    <h:outputText value="#{embeddableJSFBean.operationMessage}"/>
                </h:panelGrid>
            </h:form>
        </center>
    </h:body>
</html>

Index kodumuz içinde projenin web sayfasını yazıyoruz.

EmbeddableJSFBean.java

package embeddable;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class EmbeddableJSFBean {
    @EJB
    private EmbeddableEJBBeanLocal eJBBeanLocal;
    
    Embdeddabletable embdeddabletable = new Embdeddabletable();
    Accessing accessing = new Accessing();
    String operationMessage;
    
    public Embdeddabletable getEmbdeddabletable() {
        return embdeddabletable;
    }

    public void setEmbdeddabletable(Embdeddabletable embdeddabletable) {
        this.embdeddabletable = embdeddabletable;
    }

    public Accessing getAccessing() {
        return accessing;
    }

    public void setAccessing(Accessing accessing) {
        this.accessing = accessing;
    }

    public String getOperationMessage() {
        return operationMessage;
    }

    public void setOperationMessage(String operationMessage) {
        this.operationMessage = operationMessage;
    }
    
    public void callEJBMethod()
    {
        embdeddabletable.setAccessing(accessing);

        operationMessage=eJBBeanLocal.addPerson(embdeddabletable);
    }
}

JSF Managed Bean’i içerisinde EJB metodumuzu çağırabilmek için @EJB notasyonu ile bir arabirim nesnesini gömüyoruz.  Akabinde Java sınıfına haritaladığımız tablomuz için bir Embdeddabletable nesnesi ve Embeddable olarak kullanacağımız POJO olan Accessing sınıfından bir nesne oluşturuyoruz. Bunun dışındakiler bildiğimiz şeyler.

Accessing.java

package embeddable;

import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class Accessing implements Serializable{
    private String address;
    private String telephone;

    public String getAddress() {
        return address;
    }

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

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }
}

Accessing sınıfı bizim tablomuzdaki adres ve telephone kısımlarını yönetmek için yazdığımız bir POJO. Eğer bizler EJB’nin Persistence mekanizması içersinde bir POJO vasıtası ile alanları yönetme işine girişecek isek bu sınıfı @Embeddable notasyonu ile işaretlememiz gerekir. Bunun dışında yapılması gereken özel bir işlem yoktur.

Embdeddabletable.java

package embeddable;

import java.io.Serializable;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table(name = "embdeddabletable")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Embdeddabletable.findAll", query = "SELECT e FROM Embdeddabletable e"),
    @NamedQuery(name = "Embdeddabletable.findById", query = "SELECT e FROM Embdeddabletable e WHERE e.id = :id"),
    @NamedQuery(name = "Embdeddabletable.findByName", query = "SELECT e FROM Embdeddabletable e WHERE e.name = :name"),
    @NamedQuery(name = "Embdeddabletable.findBySurname", query = "SELECT e FROM Embdeddabletable e WHERE e.surname = :surname")})
public class Embdeddabletable implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "address",column = @Column(name = "adres")),
        @AttributeOverride(name = "telephone",column = @Column(name = "telephone"))
    })
    private Accessing accessing;

    public Accessing getAccessing() {
        return accessing;
    }

    public void setAccessing(Accessing accessing) {
        this.accessing = accessing;
    }
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 50)
    @Column(name = "name")
    private String name;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 50)
    @Column(name = "surname")
    private String surname;
    
    public Embdeddabletable() {
    }

    public Embdeddabletable(Integer id) {
        this.id = id;
    }

    public Embdeddabletable(Integer id, String name, String surname, String adres, String telephone) {
        this.id = id;
        this.name = name;
        this.surname = surname;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }
    
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Embdeddabletable)) {
            return false;
        }
        Embdeddabletable other = (Embdeddabletable) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "embeddable.Embdeddabletable[ id=" + id + " ]";
    }
    
}

Tablonun Java sınıfına haritalanmış hali. Dikkat eder isek adres ve telephone kısımları Entity sınıfı içinde yok. Bu alanlar Accessing nesnesi ile yönetilecek. Accessing nesnesi ile yönetebilmek için de  oluşturulan Accessing nesnesinin iki notasyon ile işaretlenmesi gerekir. Birincisi @Embeddable notasyonudur. Bu notasyon @Embedded notasyonu işaretlenmiş sınıftan oluşturulmuş nesneyi kullanmak için gereklidir. İkinci notasyon ise @AttributeOverrides notasyonudur. @AttributeOverrides notasyonunun içinde @Embeddable notasyonu ile işaretlediğimiz sınıf içindeki alanları parametre olarak geçiriyoruz. Bu geçirme işlemini de @AttributeOverride notasyonu ile yapıyoruz. @AttributeOverride notasyonuna da parametre olarak name ve column veriyoruz. name POJO içinde tanımlanmış olan kolona karşılık gelen değişkenin adı, column da kolonun adıdır. @Embedded ve @AttributeOverrides notasyonu ile işretlenmiş olan Accessing değişkenin get&set metotlarını da yazıp işlemi tamamlıyoruz.

EmbeddableEJBBeanLocal.java

package embeddable;

import javax.ejb.Local;

@Local
public interface EmbeddableEJBBeanLocal {
    public String addPerson(Embdeddabletable embdeddabletable);
}

EJB sınıfı için yazılar interface. Bildiğimiz gibi EJB’lere direk erişim tavsiye edilen,doğru birşey değil. Bunun için bir arabirim (interface) yazıp EJB sınıfını ondan implement ediyoruz.

EmbeddableEJBBean.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package embeddable;

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

/**
 *
 * @author ilkaygunel
 */
@Stateless
public class EmbeddableEJBBean implements EmbeddableEJBBeanLocal 
{
    @PersistenceContext
    EntityManager em;
    
    @Override
    public String addPerson(Embdeddabletable embdeddabletable) 
    {
        try {
            em.persist(embdeddabletable);
            return "Kayıt Ekleme İşlemi Başarılı!";
        } catch (Exception e) 
        {
            System.err.println("Hata!!!"+e);
            return "Kayıt Ekleme İşlemi Başarısız!";
        }
    }
    
}

İnceleyeceğimiz son kodumuz da EJB Bean’imiz. EJB sınıfımız içinde persist işlemi gerçekleştiriliyor. Orada dikkatinizi çekerim persist işlemi sırasında bizim açıp kapattığımız bir Transaction mekanizması yok. Burada @PersistenceContext notasyonu ile Transaction mekanizmasının yönetimi sunucuya bırakılıyor ve bizler açıkçası benim dertli gördüğüm noktalardan birinden daha kurtulmuş oluyoruz.

Ekran Çıktıları

Proje çalıştığında gelen ekranı şu şekilde dolduruyorum.

Screen Shot 2015-12-05 at 20.50.41

KAYDET butonuna tıkladığımda bana kayıt ile ilgili mesaj döndürülüyor. Kayıt başarı ile yapıldı.

Screen Shot 2015-12-05 at 20.52.49

MySQL veri tabanına gidip verinin düzgün kaydedilip edilmediğine bakalım. Veri karakter kodlaması da dahil düzgün bir şekilde veri tabanına kaydedilmiş. Id noktasına aklı takılan olursa o yazıyı yazmadan önce test amaçlı eklediğim ilk kayıttan dolayı 2. 🙂

Screen Shot 2015-12-05 at 20.54.36

Bu yazıda da bu kadar arkadaşlar. Embeddable Object’in ne olduğunu ve nasıl kullanıldığını öğrenmiş olduk. Gelecek yazıda görüşmek üzere sağlıcakla kalın arkadaşlar.

Yorum Yap