disseny de la persistència hibernate i frameworks de persistència pojo
DESCRIPTION
Disseny de la persistència Hibernate i frameworks de persistència POJO. Toni Navarrete Enginyeria del Software II – UPF 200 7. Recordatori: problemes (i aventatges) d’altres solucions. Serialitzatió Avantantges: Estàndard en qualsevol ambient Java Fàcil d’utilitzar - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/1.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Disseny de la persistènciaHibernate i frameworks de persistència POJO
Toni Navarrete
Enginyeria del Software II – UPF 2007
![Page 2: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/2.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 2
Recordatori: problemes (i aventatges) d’altres solucions
• Serialitzatió– Avantantges:
• Estàndard en qualsevol ambient Java• Fàcil d’utilitzar• El model de dades és directament el de les
classes (aprofita OO)
– Inconvenients:• No té les característiques d’un gestor de BD
robust– Per exemple, índexs, transaccions,...
• No és escalable
![Page 3: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/3.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 3
Recordatori: problemes (i aventatges) d’altres solucions
• JDBC– Permet treballar amb un Gestor de BD– Dóna accés a SQL– Usa el model relacional
• No el model orientat a objectes de Java• Procedimental en lloc d’OO• El processament de dades es fa mitjançant SQL i no Java
– Les operacions són expressades en relació a taules, files i columnes, referides a l’esquema de la BD
– SQL no està realment estandaritzat, amb la qual cosa la portabilitat no sempre és total
![Page 4: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/4.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 4
Recordatori: problemes (i aventatges) d’altres solucions
• Quan s’utilitza JDBC, el programador està obligat a treballar amb dos models de dades diferents, així com amb dos paradigmes i llenguatges d’accés a les dades distints– Si cal canviar l’esquema de la BD també cal
canviar les classes– El resultat sol ser que s’escriu codi Java
procedural per manipular les taules. No OO
![Page 5: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/5.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 5
Recordatori: problemes (i aventatges) d’altres solucions
• EJB 2.1 i la persistència manegada pel contenidor (CMP)– Defineix un mecanisme de persistència
transparent• Els mètodes dels EJB d’entitat són independents
de l’esquema de dades• Llenguatge de consultes abstracte, independent
de SQL
– EJB és una arquitectura complexa i amb un alt overhead
![Page 6: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/6.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 6
Objectius dels frameworks de persistència POJO (Plain Old Java Object)• Treballar amb el model de classes i deixar al
framework de persistència la traducció al model relacional– Normalment el mapping s’especifica mitjançant un
fitxer XML
• Operacions d’accés a la BD referides a:– Guardar objectes (inserts)– Modificar objectes (updates)– Eliminar objectes (deletes)– Recuperar col·leccions d’objectes (selects)
• Independència entre el model de classes i el model físic de la BD
mínima intrusió i màxima transparència
![Page 7: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/7.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 7
Hibernate
• Hibernate és un d’aquests frameworks de persistència POJO
• Codi obert i gratuït (llicència GNU LGPL)
• Molt estès, gran comunitat de desenvolupadors i usuaris
![Page 8: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/8.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 8
Problemes dels frameworks de persistència
• Adoptar un API no estandaritzada és sempre arriscat
• A moltes implementacions:– Falta d’encapsulació causada per la
necessitat de definir mètodes getter i setter públics per als atributs persistents
– Extensibilitat limitada per la falta de soport de l’herència
– Falta de soport de referències polimòrfiques
• Dependència absoluta del framework
![Page 9: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/9.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 9
JDO
• És una iniciativa de la comunitat Java per crear un framework estandaritzat per a persistència (de la mateixa forma que Swing ho és per a interfície gràfica)
• JDO és només una especificació, de la qual els fabricants de software faran implementacions (a vegades lliures, a vegades no)– JPOX és la implementació de referència (i lliure), però no és
prou estable• JDO pot suportar no només BD relacionals sinó
qualsevol forma d’emmagatzemantge permanent (XML, fitxers,...)
• És molt “transparent” (per exemple, persistència transitiva)
• No ha acabat de consolidar-se com a estàndard• Actualment un projecte Apache: http://db.apache.org/jdo/
![Page 10: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/10.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 10
Java Persistence API (JPA)
• Definida en EJB 3.0 (JavaEE 5)http://java.sun.com/javaee/technologies/persistence.jsp
• La idea original era que JPA es fes a partir de JDO, però ha acabat essent una especificació diferent– http://db.apache.org/jdo/jdo_v_jpa.html– http://db.apache.org/jdo/jdo_v_jpa_orm.html
• JPA substitueix als EJB d’entitat– Ja no cal definir les interfícies– No s’utilitza el deployment descriptor
![Page 11: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/11.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 11
Java Persistence API (JPA)
![Page 12: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/12.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 12
JPA
![Page 13: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/13.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 13
Hibernate i els estàndards
• Hibernate no té cap relació amb JDO
• Té una API “EntityManager” per permetre compatibilitat amb Java Persistenca API
![Page 14: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/14.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 14
Nota: Hibernate i JDBC
• Hibernate no substitueix JDBC– Són complementaris– Hibernate utilitza JDBC per sota per
connectar-se a la BD• JDBC és útil per gestionar connexions amb la BD• JDBC és força sòlid• JDBC està soportat per la majoria de fabricants
de SGBD
![Page 15: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/15.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 15
Exemple d’una petita aplicació amb Hibernate
• Farem una classe que permet guardar a la BD instàncies d’una classe Persona
• Una altra classe ens permetrà recuperar les instàncies de Persona a la BD
![Page 16: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/16.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 16
La classe Persona
package persones;public class Persona { Long id; //a Hibernate cal definir un identificador d’instància, amb els seus mètodes get i set String nom, cognom; int anyNaixement = 0; public Persona() {} // a Hibernate és obligatori que hi hagi un constructor sense arguments public Persona(String nom, String cognom, int anyNaixement) { this.nom = nom; this.cognom = cognom; this. anyNaixement = anyNaixement; } public Long getId() { return id; } private void setId(Long id) { this.id = id; } public void setNom(String nom) { this.nom = nom; } public String getNom() { return this.nom; } public void setCognom(String cognom) { this.cognom = cognom; } public String getCognom() { return this.cognom; } public void setAnyNaixement(int anyNaixement) { this. anyNaixement = anyNaixement; } public int getAnyNaixement() { return this.anyNaixement; }}
![Page 17: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/17.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 17
Mapeig entre classe i taula(es) de la BD
• Fitxer persona.hbm.xml<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="persones">
<class name="Persona" table="PERSONA">
<id name="id" column="PERSONA_ID">
<generator class="native"/>
</id>
<property name="nom"/>
<property name="cognom"/>
<property name="anyNaixement"/>
</class>
</hibernate-mapping>
![Page 18: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/18.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 18
• Fitxer hibernate.cfg.xml<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Propietats de la BD -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate_db1
</property>
<property name="connection.username">usuari</property>
<property name="connection.password">password</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
Configuració del gestor de BD (i altres propietats)
![Page 19: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/19.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 19 Configuració del gestor de BD (i altres propietats)• Fitxer hibernate.cfg.xml
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Esborra i torna a crear l’esquema de la BD a cada execució (només per proves) -->
<!-- Cal comentar-ho quan volguem fer consultes!!!-->
<property name="hbm2ddl.auto">create</property>
<!-- Referència al(s) fitxer(s) de mapping -->
<mapping resource="persones/Persona.hbm.xml"/>
</session-factory>
</hibernate-configuration>
![Page 20: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/20.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 20 Inserció d’instànciespackage persones;
import org.hibernate.*; import org.hibernate.cfg.*;
public class Insercions {
static Session session;
static SessionFactory sessionFactory;
public static void main(String[] args) {
try {
// Crea la Session de hibernate a partir del fitxer hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
session = sessionFactory.getCurrentSession();
//comença la transacció
session.beginTransaction();
//crea les instàncies que calgui i les guarda
Persona p1 = new Persona("pep", "garcia", 1970);
Persona p2 = new Persona("josep", "fernandez", 1965);
session.save(p1);
session.save(p2);
//fa el commit de la transacció
session.getTransaction().commit();
//tanca el sessionFactory i allibera els recursos associats (caches, pools,…)
sessionFactory.close();
} catch (RuntimeException e) {
if (session!=null) session.getTransaction().rollback();
e.printStackTrace();
}
}
}
![Page 21: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/21.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 21 Consulta d’instànciespackage persones;
import org.hibernate.*; import org.hibernate.cfg.*;
public class Consulta {
static Session session; static SessionFactory sessionFactory;
public static void main(String[] args) {
try {
// Crea la Session de hibernate a partir del fitxer hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
session = sessionFactory.getCurrentSession();
//comença la transacció
session.beginTransaction();
//recupera les instàncies de la classe Persona i escriu els seus atributs per pantalla
java.util.Iterator it = session.createQuery("from Persona").list().iterator();
while (it.hasNext()) {
Persona p = (Persona)it.next();
System.out.println("Nom: "+p.getNom());
System.out.println("Cognom: "+p.getCognom());
System.out.println("Any naixement: "+p.getAnyNaixement());
}
//fa el commit de la transacció
session.getTransaction().commit();
// tanca el sessionFactory i allibera els recursos associats (caches, pools,…) //
sessionFactory.close();
} catch (RuntimeException e) {
if (session!=null) session.getTransaction().rollback();
e.printStackTrace();
}
}
}
![Page 22: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/22.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 22 Modificació d’instànciespackage persones;
import org.hibernate.*; import org.hibernate.cfg.*;
public class Modificacio {
static Session session; static SessionFactory sessionFactory;
public static void main(String[] args) {
try {
// Crea la Session de hibernate a partir del fitxer hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
session = sessionFactory.getCurrentSession();
//comença la transacció
session.beginTransaction();
//recupera les instàncies de la classe Persona
java.util.Iterator it = session.createQuery("from Persona").list().iterator();
while (it.hasNext()) {
Persona p = (Persona)it.next();
if (p.getNom().equals("pep"))
p.setNom("josep");
}
//fa el commit de la transacció
session.getTransaction().commit();
// tanca el sessionFactory i allibera els recursos associats (caches, pools,…) //
sessionFactory.close();
} catch (RuntimeException e) {
if (session!=null) session.getTransaction().rollback();
e.printStackTrace();
}
}
}
NOTA: si l’objecte que modifiquem no s’ha guardat o recuperat en la mateixa transacció, cal afegir
session.update(p);
En l’exemple això no és necessari
![Page 23: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/23.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 23 Esborrat d’instànciespackage persones;
import org.hibernate.*; import org.hibernate.cfg.*;
public class Esborrat {
static Session session; static SessionFactory sessionFactory;
public static void main(String[] args) {
try {
// Crea la Session de hibernate a partir del fitxer hibernate.cfg.xml
sessionFactory = new Configuration().configure().buildSessionFactory();
session = sessionFactory.getCurrentSession();
//comença la transacció
session.beginTransaction();
//recupera les instàncies de la classe Persona i escriu els seus atributs per pantalla
java.util.Iterator it = session.createQuery("from Persona").list().iterator();
while (it.hasNext()) {
Persona p = (Persona)it.next();
if (p.getAnyNaixement()<1970)
session.delete(p);
}
//fa el commit de la transacció
session.getTransaction().commit();
// tanca el sessionFactory i allibera els recursos associats (caches, pools,…) //
sessionFactory.close();
} catch (RuntimeException e) {
if (session!=null) session.getTransaction().rollback();
e.printStackTrace();
}
}
}
![Page 24: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/24.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 24
Més sobre consultes• Les consultes s’expressen en HQL
– Sempre fent referència al model de classes, no al de la BD• Exemple: persones nascudes abans d’un cert any:
public static void imprimeixLlistatAbansAny(int any) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); java.util.Iterator it = session.createQuery( "from Persona p where p.anyNaixement < ?") .setInteger(0, any) .list().iterator();
while (it.hasNext()) { Persona p = (Persona)it.next(); System.out.println("Nom: "+p.getNom()); System.out.println("Cognom: "+p.getCognom()); System.out.println("Any naixement: "+p.getAnyNaixement()); } session.getTransaction().commit(); HibernateUtil.getSessionFactory().close(); }
![Page 25: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/25.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 25
Altres exemples de consultes
• PaginacióQuery q = session.createQuery("from Persona"); q.setFirstResult(20); q.setMaxResults(10);List persones = q.list();
• OrdenacióQuery q = session.createQuery(
"from Persona p order by p.cognom");
• AgregacionsQuery q = session.createQuery(
"select avg(p.pes), sum(p.pes), max(p.pes), count(p) from Persona p");
![Page 26: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/26.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 26
Recuperar objecte per ID
• L’objecte de sessió té un mètode load que permet recuperar un objecte persistent si sabem el seu identificador:
Persona p = (Persona) session.load(
Persona.class, new Long(1234) );
![Page 27: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/27.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 27
Estats d’una instància
• transient– La instància no està, i no ha estat mai, associada a un context de
persistència (sessió). No té un id persistent (valor de clau primària)• persistent
– La instància està associada a un context de persistència (sessió). Té un id persistent i normalment està associada a una fila en la BD. Hibernate garantitza que l’estat de la instància és equivalent a l’estat persistent, mentre segueixi associat a la transacció
• detached– La instància va estar associada amb un context de persistència
(sessió), però aquest es va tancar. Té un id persistent i normalment està associada a una fila en la BD, però els canvis en l’estat de la instància no es veuen reflectits a la BD
• Notes:– Totes les comunicacions amb la BD (lectures i escriptures) es fan dins
d’una transacció– En els nostres exemples, una sessió (un context de persistència) està
emmarcada per una transacció. Més endavant veurem que aquest patró es pot canviar
![Page 28: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/28.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 28
Flush d’una sessió
• Totes les instàncies amb estat “persistent” que es modifiquen dins d’una sessió es poden actualitzar a la BD directament cridant el mètode flush (sense haver de fer-ho un a un)Persona p1 = (Persona) session.load(Persona.class, new Long(1) );
Persona p2 = (Persona) session.load(Persona.class, new Long(2) );
p1.setNom(“joan”);
p2.setNom(“jordi”);
session.flush();
![Page 29: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/29.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 29
Millorant l’estructurapackage util;import org.hibernate.*;import org.hibernate.cfg.*;
public class HibernateUtil {
private static final SessionFactory sessionFactory; static { try { // Create the SessionFactory from hibernate.cfg.xml sessionFactory = new
Configuration().configure().buildSessionFactory(); } catch (Exception e) { e.printStackTrace(); throw new ExceptionInInitializerError(e); } }
public static SessionFactory getSessionFactory() { return sessionFactory; }}
![Page 30: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/30.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 30
package persones;import org.hibernate.*; import org.hibernate.cfg.*; import util.HibernateUtil;
public class Persona { Long id; String nom, cognom; int anyNaixement = 0; public Persona() {}
//Constructors, gets i sets i altres mètodes
public void guarda() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.save(this); session.getTransaction().commit(); HibernateUtil.getSessionFactory().close(); }
![Page 31: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/31.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 31
public void esborra() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.delete(this); session.getTransaction().commit(); HibernateUtil.getSessionFactory().close(); }
public void actualitza() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.update(this); session.getTransaction().commit(); HibernateUtil.getSessionFactory().close(); } public static java.util.List getLlistaPersones() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); java.util.List persones = session.createQuery("from Persona").list();
session.getTransaction().commit(); HibernateUtil.getSessionFactory().close(); return persones; } }
![Page 32: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/32.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 32
package clients;import org.hibernate.*; import org.hibernate.cfg.*; import persones.*;public class Client { public static void main(String[] args) { //crea les instàncies que calgui i les guarda Persona p1 = new Persona("pep", "garcia", 1970); Persona p2 = new Persona("josep", "fernandez", 1965); p1.guarda(); p2.guarda();
java.util.List persones = Persona.getLlistaPersones(); java.util.Iterator it = persones.iterator();
while (it.hasNext()) { Persona p = (Persona)it.next(); if (p.getNom().equals("pep")) p.esborra(); else { p.setNom(p.getNom().toUpperCase()); p.setCognom(p.getCognom().toUpperCase()); p.actualitza(); System.out.println("Nom: "+p.getNom()); System.out.println("Cognom: "+p.getCognom()); System.out.println("Any naixement: "+p.getAnyNaixement()); } } }}
![Page 33: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/33.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 33
Un exemple més complet (amb herència i associacions)
Persona
Empleat
Grup0..*0..*
![Page 34: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/34.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 34
Fitxers de mapping
• Un per classe o un per tot el paquet• Herència
– Cal definir entre les tres formes d’implementar l’herència
– Si és el cas, cal definir quin atribut s’utilitza com a discriminador, i quin valor pren cada subclasse
• Associacions– 1-a-1, 1-a-molts o molts-a-molts– Unidireccionals o bidireccionals– Amb o sense taula de join
![Page 35: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/35.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 35
<hibernate-mapping package="persones"> <class name="Persona" table="PERSONA"> <id name="id" column="PERSONA_ID"> <generator class="native"/> </id> <discriminator column="TIPUS" type="string"/> <property name="nom"/> <property name="cognom"/> <property name="anyNaixement"/>
<subclass name="Empleat" extends="Persona" discriminator-value="persones.Empleat">
<property name="salari"/> </subclass> </class> <class name="Grup" table="GRUP"> <id name="id" column="GRUP_ID"> <generator class="native"/> </id> <property name="nom"/>
<set name="persones" table="GRUP_PERSONA"> <key column="GRUP_ID"/> <many-to-many column="PERSONA_ID" class="Persona"/> </set> </class></hibernate-mapping>
![Page 36: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/36.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 36
package persones;import java.util.*; import org.hibernate.*; import org.hibernate.cfg.*;public class Insercions { public static void main(String[] args) { try { // Crea la Session de hibernate a partir del fitxer hibernate.cfg.xml SessionFactory sessionFactory =
new Configuration().configure().buildSessionFactory(); Session session = sessionFactory.getCurrentSession(); //comença la transacció session.beginTransaction(); //crea les instàncies que calgui i les guarda Persona toni = new Persona("toni","navarrete",1973); session.save(toni); Persona dani = new Persona("dani","soto",1973); session.save(dani); Empleat pep = new Empleat("pep","garcia",1977,30000); session.save(pep); Grup g = new Grup("grupo 1"); Set s = new HashSet(); s.add(toni); s.add(pep); g.setPersones(s); session.save(g); //fa el commit de la transacció session.getTransaction().commit(); sessionFactory.close(); } catch (Exception e) { e.printStackTrace(); } }}
![Page 37: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/37.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 37
package persones;import java.util.*; import org.hibernate.*; import org.hibernate.cfg.*;public class Consultes { public static void main(String[] args) { try { // Crea la Session de hibernate a partir del fitxer hibernate.cfg.xml SessionFactory sessionFactory =
new Configuration().configure().buildSessionFactory(); Session session = sessionFactory.getCurrentSession(); //comença la transacció session.beginTransaction(); //recupera les instàncies de la classe Grup java.util.List grups = session.createQuery("from Grup").list(); System.out.println("Nombre de grups: "+grups.size()); for (int i=0;i<grups.size();i++) { Grup g = (Grup)grups.get(i); System.out.println(" Nom: "+g.getNom()); System.out.println(" Número de membres: "+g.getPersones().size()); java.util.Iterator it = g.getPersones().iterator(); while (it.hasNext()) { Persona p = (Persona)it.next(); System.out.println(" Nom: "+p.getNom()+" "+p.getCognom()); if (p instanceof Empleat) System.out.println(" Salari: "+((Empleat)p).getSalari()); } } //fa el commit de la transacció session.getTransaction().commit(); sessionFactory.close(); } catch (Exception e) { e.printStackTrace(); }}
![Page 38: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/38.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 38
Consultes amb joins
• Un empleat pertany a 1 departament, un departament té molts empleats– Empleat té un atribut departament– Departament té un atribut col·lecció empleats
• Empleats d’un departament:– “from Empleat e where
e.departament.nom=‘Informàtica’ ”– “select e
from Empleat e join e.departament d
where d.nom=‘Informàtica’ ”
![Page 39: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/39.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 39
Aspectes a tenir en compte sobre les referències i col·leccions
• Persistència transitiva– Quan guardem una instància, cal també guardar
expressament cada una de les instàncies referenciades per ella (no com amb serialització o JDO)
– Per evitar això: es pot configurar al fitxer de mapping:• <one-to-many name="persones" cascade="persist"/>• <one-to-many name="persones"
cascade="persist,delete,lock"/>
– Quan recuperem una instància, podem recuperar les seves referències a altres instàncies sense haver de definir una altra consulta
![Page 40: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/40.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 40
Aspectes a tenir en compte sobre les referències i col·leccions
• Lazy associations– Quan recuperem una instànica (grup), la
col·lecció d’instàncies referenciades (conjunt de persones) no es carrega en memòria fins que no s’hi accedeix
– Aquest comportament per defecte es pot modificar: diverses formes de fetching i caches
• Instàncies detached– Quan recuperem una instància dins d’una
transacció, un cop es tanca la transacció, no podem accedir a les seves referències
![Page 41: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/41.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 41
Arquitectura
![Page 42: Disseny de la persistència Hibernate i frameworks de persistència POJO](https://reader036.vdocuments.pub/reader036/viewer/2022070409/568144ca550346895db1934a/html5/thumbnails/42.jpg)
En
gin
yeri
a d
el S
W II
: Dis
sen
y d
e la
pe
rsis
tèn
cia
. H
iber
na
te i
fra
me
wo
rks
de
per
sist
ènc
ia P
OJO
Pàgina 42
Sessions i transaccions
• El patró més habitual és el de session-per-request (no necessàriament session-per-operation)
• Converses més llargues– No és viable mantenir oberta una sessió
entre diferents peticions o per una aplicació– session-per-request-with-detached-objects– session-per-conversation (la sessió es pot
desconnectar de la capa de JDBC després d’un commit, i tornar a connectar quan rep una altra petició del mateix client)