Friday 23 April 2010

Entităţi JPA în Java EE 6

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

Monday 19 April 2010

Blog Companion Google Group

I created a companion Google Group, so that I can upload files and you can ask questions or comment independently of my posts.

The group name is Cristina's Java EE Blog Companion and it can be accessed at the address http://groups.google.com/group/java-ee-blog-companion.

Anybody can view group content but only members can post messages. If you want to be a member, please let me know.

Wednesday 14 April 2010

Definirea unei surse de date Java DB in GlassFish V3

Crearea şi distrugerea conexiunilor la o bază de date poate fi costisitoare, ceea ce justifică menţinerea unui "rezervor de conexiuni'' (connection pool), o mulţime de conexiuni reutilizabile, pentru o anumită bază de date, pregătite în prealabil şi administrate de către serverul de aplicaţii. Definiţia unei surse de date în GlassFish trebuie să fie precedată de definiţia rezervorului de conexiuni folosit de aceasta. Am definit rezervorul de conexiuni şi sursa de date folosind consola grafică pentru administrare a serverului, aşa cum se vede în figurile următoare.

 Pentru ca definiţia unui rezervor de conexiuni pe o bază de date Java DB să fie completă trebuie definite şi următoarele proprietăţi: DatabaseName, User, Password, PortNumber, ServerName. Mai jos este specificat ca exemplu un set de valori pentru aceste proprietăţi.

DatabaseName = C:\Sun\SDK\javaDB\bin\student
User = profesor
Password = parolaprofesor
PortNumber = 1527
ServerName = localhost

Monday 12 April 2010

Build and Test a Simple Session Bean Revisited

Pentru a testa funcţionarea componentei se vor parcurge următorii paşi:

1. C:\EJB>set CLASSPATH=.;C:\glassfishv3\glassfish\lib\javaee.jar

2. Se compilează interfaţa componentei, clasa care o implementează şi programul client:

C:\EJB>javac -d . firstBean/*.java

C:\EJB>javac -d . firstBeanClient/*.java

3. Se împachetează clasa şi interfaţa corespunzătoare componentei de tip sesiune în arhiva FirstBeanJar.jar:

C:\EJB>jar cvf FirstBeanJar.jar firstBean\

4. Se încarcă arhiva FirstBeanJar.jar pe serverul de aplicaţii, folosind, de exemplu, consola grafică de administrare:

















5. Se execută programul client:

C:\EJB>java -classpath C:\glassfishv3\glassfish\lib\appserv-rt.jar; C:\glassfishv3\glassfish\lib\javaee.jar; C:\EJB firstBeanClient.FirstBeanClient Cristina

Implicit serverul de aplicaţii se găseşte pe maşina locală, comanda precedentă fiind echivalentă cu următoarea:

C:\EJB>java -classpath C:\glassfishv3\glassfish\lib\appserv-rt.jar; C:\glassfishv3\glassfish\lib\javaee.jar; C:\EJB -D org.omg.CORBA.ORBInitialHost = localhost firstBeanClient.FirstBeanClient Cristina

Sunday 11 April 2010

O aplicaţie simplă cu Java DB

import java.sql.*;

public class Student {

public static void main(String[] args) {

Connection dbConnection = null;     
String dbUrl =
"jdbc:derby:C:\\Sun\\SDK\\javadb\\bin\\student;"+
"user=profesor;password=parolaprofesor";

try{
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
//incarca driver JDBC pt JavaDB
}

catch(ClassNotFoundException e) {
e.printStackTrace(); 
System.out.println("Eroare incarcare driver!\n" + e);
}

try{
dbConnection=DriverManager.getConnection(dbUrl);
Statement stmt= dbConnection.createStatement();
ResultSet  rs =
stmt.executeQuery(
" SELECT * FROM student");

while (rs.next()) {
System.out.println (
rs.getString ("nume") + "," +
rs.getString ("prenume") + "," +
rs.getString ("email"));
}
stmt.close();
}

catch(SQLException e) {
e.printStackTrace();
}
}
}
Programul se execută precizând în linia de comandă pentru maşina virtuală Java calea către driverul Java DB pentru SQL(derby.jar):

java -classpath .;C:\Sun\SDK\javadb\lib\derby.jar Student

Wednesday 7 April 2010

Introducere în Java DB

Java DB este o versiune a sistemului Derby(Apache) pentru baze de date. Această versiune este dezvoltată în întregime în tehnologie Java şi este în prezent "împachetată" în serverul de aplicaţii GlassFish.

Execuţia comenzilor SQL

Instrumentul pe care îl avem la dispoziţie pentru execuţia comenzilor SQL în Java DB, atât a comenzilor de interogare cât şi a celor de creare a tabelelor şi manipulare a datelor, se numeşte ij. Interfaţa utilizatorului cu ij este linia de comandă.

Pe calculatorul meu, ij se găseşte în directorul C:\Sun\SDK\javadb\bin. Pentru a deschide o conexiune la baza de date, a crea o tabelă şi a insera valori în aceasta am executat următoarele comenzi:

C:\Sun\SDK\javadb\bin>ij

ij>connect 'jdbc:derby:student;
create=true; user=profesor;
password = parolaprofesor'
as my_connection;

ij>CREATE TABLE t1(
nume VARCHAR(30),
varsta INTEGER);

ij>INSERT INTO t1 VALUES
('Cristina',31);

ij>SELECT * FROM t1;

ij>exit;

C:\Sun\SDK\javadb\bin>