Clasa corespunzătoare unei tabele relaţionale
Java EE foloseşte standardul JPA(Java Persistence API) pentru realizarea corespondenţei dintre obiecte Java şi tabele ale unei baze de date relaţionale. Între aplicaţie, care foloseşte modelul bazat pe obiecte, şi schema bazei de date există în Java EE un nivel numit ``de persistenţă'', care izolează programatorul de problemele specifice bazei de date (e.g. gestiunea tranzacţiilor). O tabelă dintr-o bază de date relaţională este reprezentată în program printr-o
entitate JPA, o clasă Java marcată cu adnotarea
@Entity.
O instanţă a unei entităţi JPA corespunde unei linii din tabela asociată.
Corespondenţa dintre o entitate JPA şi o tabelă din baza de date se realizează folosind adnotări în clasa Java care reprezintă entitatea JPA. Astfel, de exemplu,
@Table specifică numele tabelei cu care entitatea este asociată,
@Column desemnează numele coloanei din tabelă cu care este asociat câmpul marcat al entităţii JPA,
@Id marchează un câmp al entităţii care corespunde unei chei primare in tabela asociată.
Mai jos se găseşte definiţia clasei Student, entitatea JPA corespunzătoare unei tabele STUDENT.
package doi;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
import java.io.Serializable;
@Entity
@Table(name="STUDENT")
public class Student implements Serializable{
@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;
@Column(name="NUME")
private String nume;
@Column(name="PRENUME")
private String prenume;
@Column(name="EMAIL")
private String email;
public Student(){
}
public long citesteStudentId(){
return studentId;
}
public void scrieStudentId(int i){
studentId=i;
}
public String citesteNume(){
return nume;
}
public void scrieNume(String n){
nume=n;
}
public String citestePrenume(){
return prenume;
}
public void scriePrenume(String p){
prenume=p;
}
public String citesteEmail(){
return email;
}
public void scrieEmail(String e){
email=e;
}
}
Componenta de tip sesiune, faţada componentei de tip entitate
Găsirea, actualizarea, crearea şi ştergerea obiectelor asociate cu linii dintr-o tabelă relaţională (găsirea, actualizarea, crearea şi ştergerea entităţilor JPA) se face prin intermediul unor metode specificate de interfaţa
EntityManager, care face parte din standardul JPA.
Pentru a obţine o instanţă de tip
EntityManager se foloseşte adnotarea
@PersistenceContext pentru a injecta gestionarul de entităţi JPA în componenta care operează cu entităţi JPA.
Accesul la o componentă de tip entitate este implementat prin intermediul unei componente de tip sesiune. Definim în continuare interfaţa şi clasa corespunzătoare componentei
CautaStudent, o componentă de tip sesiune, fără stare, care defineşte metoda
cauta(int id). Rezultatul metodei
cauta reprezintă numele studentului cu id-ul dat ca argument, obţinut prin folosirea metodei
find() a gestionarului de entităţi
em. La apelul metodei
find(), gestionarul de entităţi extrage înregistrarea căutată din baza de date şi instanţiază cu valorile obţinute un obiect de tipul corespunzător (în exemplul nostru de tipul
Student).
Definiţia interfeţei
package doi;
import javax.ejb.Remote;
import doi.Student;
@Remote
public interface CautaStudent{
public String cauta(int id);
}
Definiţia clasei
package doi;
import javax.ejb.Stateless;
import javax.annotation.Resource;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import doi.Student;
@Stateless(name="CautaStudent")
public class CautaStudentBean implements CautaStudent{
@PersistenceContext(unitName="StudentPersistUnit")
EntityManager em;
public String cauta(int id){
Student s = em.find(Student.class,id);
return s.citesteNume();
}
}
Compilaţi entitatea JPA, interfaţa şi clasa corespunzătoare componentei de tip sesiune, folosind următoarele comenzi:
C:\EJB>set CLASSPATH=.;C:\glassfishv3\glassfish\lib\javaee.jar
C:\EJB>javac -d . doi/Student.java
C:\EJB>javac -d . doi/CautaStudent.java
C:\EJB>javac -d . doi/CautaStudentBean.java
Definirea unităţii de persistenţă
O unitate de persistenţă defineşte mulţimea tuturor entităţilor JPA dintr-o aplicaţie administrate de instanţe de tipul EntityManager şi specifică numele global JNDI al sursei de date corespunzătoare. Unităţile de persistenţă sunt definite în fişierul de configurare
persistence.xml, care trebuie să se găsească în directorul META-INF al unei arhive EJB-JAR.
Pentru exemplul considerat am creat în directorul C:\EJB\META-INF fişierul persistence.xml redat mai jos, care specifică numele sursei de date folosite de către containerul EJB (jdbc/student) şi numele clasei de persistenţă gestionată de EntityManager (doi.Student).
<persistence>
<persistence-unit name="StudentPersistUnit">
<description>
Prima unitate de persistenta.
Administreaza date referitoare la studenti.
</description>
<jta-data-source>jdbc/student</jta-data-source>
<class>doi.Student</class>
</persistence-unit>
</persistence>
Construiţi arhiva
MyStudentApp.jar folosind următoarea comandă:
C:\EJB> jar cvf MyStudentApp.jar doi/CautaStudent.* doi/CautaStudentBean.* doi/Student.* META-INF/persistence.xml
Încărcaţi arhiva MyStudentApp.jar pe serverul de aplicaţii, folosind consola grafică de administrare şi specificând tipul arhivei ca fiind
EJB Jar.
Un exemplu de client
package clienti;
import doi.CautaStudent;
import javax.naming.InitialContext;
import doi.Student;
public class EntityBeanStudentClient{
public static void main(String[] args) throws Exception
{
InitialContext ctx = new InitialContext();
CautaStudent beanInstance = (CautaStudent)
ctx.lookup(CautaStudent.class.getName());
String myName=beanInstance.cauta(777);
System.out.println("Hi, "
+ myName + "!");
}
}
Compilaţi şi executaţi programul client folosind următoarele comenzi:
C:\EJB>javac -d . clienti/EntityBeanStudentClient.java
C:\EJB>java -classpath C:\glassfishv3\glassfish\lib\appserv-rt.jar;C:\glassfishv3\glassfish\lib\javaee.jar;. clienti.EntityBeanStudentClient