Disseny de la persistència Hibernate i frameworks de persistència POJO

Slides:



Advertisements
Presentaciones similares
Esquema de Mapeo de Base de Datos Relacionales a Objetos
Advertisements

Lenguaje de consulta de Hibernate
Java Persistance API JPA.
CONCEPTES AVANÇATS DE SISTEMES OPERATIUS Departament d’Arquitectura de Computadors (Seminaris de CASO) Autors MULTITHREADING & JAVA SYNCHRONIZATION David.
Enginyeria del SW II: Disseny de la persistència. JDO Disseny de la persistència JDO i frameworks de persistència Toni Navarrete Enginyeria del Software.
Motor de Persistencia - Mapeos. El mapeo Objeto - Relacional es un acercamiento entre el Modelo de Objetos y el Modelo Relacional, para poder persistir.
Crear Aplicación Cliente para Conectarse a una Base de Datos.
Softlogia S.R.L. Formación de Recursos Humanos Hibernate Core Instructor: Martin R. Baspineiro.
Softlogia S.R.L. Formación de Recursos Humanos Hibernate Core Instructor: Martin R. Baspineiro.
TFG – Àrea Enginyeria del programari
Serialització i persistència
Cambios en el espacio: transformaciones geométricas
Campus Virtual.
Campus Virtual.
Projecte Fi de Carrera Disseny i desenvolupament d’un esquema criptogràfic per gestionar de forma segura els historials mèdics dels pacients a través d’una.
TFC – Aplicació web per gestionar tornejos d’escacs, amb tecnologia J2EE Alumne: Xavier Benet ETIG Consultor: Jose Juan Rodriguez Curs /1.
PROJECTE FINAL DE CARRERA
Portada. Portada Presentació: VEIEM I ESCOLTEM ALS EXPERTS Feu clic a sota.
Disseny de la interfície d’un smartwatch i l’aplicació mòbil
José Luis Molina Materiales proporcionados por Javier Ávila Molero
Google Scholar citations
Tema 2. DIVISIBILITAT.
Introducció de TEDIs (COACs) Versió 4.0
El mercat ELS NENS I NENES DE P-4.
uoc-domo CONTROL DOMÒTIC AMB ARDUINO UOC-DOMO
TFC – JEE SUPORT I SEGUIMENT TFC ANNAPURNA
TERMOREGULACIÓ HORÀRIA INDIVIDUAL DELS ESPAIS DEL CENTRE
Disseny de la persistència Hibernate i frameworks de persistència POJO
Creació d’un mapa personalitzat
Funcionament See Thecnical.
SISTEMA GESTOR D’EMPRESA D’EXCAVACIONS
Una forma fàcil d'obtenir algunes fórmules
Tutorials Campus Virtual Càrrega automàtica d’alumnes
Eines d’internet per al professorat d’EOI.
1. L’empirisme de Locke 1.3. L’anàlisi dels conceptes de la metafísica escolàstica Pàgina 258 Els dos sentits de la substància: com a substrat i com a.
WEBQUEST WEB...QUÈ ? Alumnes de l’Escola ESTEL VALLSECA.
Enginyeria del software II
Problema 1: Trobar la recta que passa pel punts A(2, -3) i B(-1, 3)
Anna Casacuberta Puig Enginyeria Informàtica Semestre Febrer 2017
Disseny de la persistència Serialització
Curs de Llenguatge Administratiu Valencià Juli Martínez Amorós
Disseny de la persistència JDO i frameworks de persistència
Jonathan Ceballos Rodriguez ( ) Zenón Perisé Alía ( )
Tema 5: Nombres naturals i enters
Optimització de consultes en MySQL (unes notes)
Disseny de la persistència Introducció i mapping objecte/relacional
Disseny de la persistència Introducció i mapping objecte/relacional
Aplicacions web bàsiques Introducció a servlets i JSP
Disseny de la persistència Serialització
Estructurant les aplicacions MVC JSTL Struts
L’electricitat i el circuit elèctric
LES XARXES LOCALS i els seus components.
Projecte Gestió de precintes de vehicles
"SENYOR, ENSENYA’M A SER FELIÇ I A DONAR PAU!"
Les taules de multiplicar
Al vostre gust amb el 8 Amb so ¯
La imatge corporativa Una eina fonamental en l’actualitat
Les fraccions Sisè B curs
Passes a seguir per iniciar un nou curs acadèmic en el GestIB
Threads en Java David Gañán Jiménez.
Jessica, Gerard, Laura P, Alex
Projecte Fi de Carrera - J2EE Alumne: Daniel Clemente Marcè
LA NOVA SELECTIVITAT I L’ACCÉS A LA UNIVERSITAT
La literatura i les matemàtiques van de la mà.
BASES DE DADES Consultes
Sistema de descàrrega d’aplicacions per a mòbils intel·ligents
Propostes de millora en el GIR
ARTS PLÀSTIQUES Eva Navas Vela 1.
LES MÀQUINES.
Estils i Plantilles Ms Word.
Transcripción de la presentación:

Disseny de la persistència Hibernate i frameworks de persistència POJO Toni Navarrete Enginyeria del Software II – UPF 2007

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

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

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

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

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

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

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

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/

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

Java Persistence API (JPA)

JPA

Hibernate i els estàndards Hibernate no té cap relació amb JDO Té una API “EntityManager” per permetre compatibilitat amb Java Persistenca API

Hibernate no substitueix JDBC 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

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

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) { public String getNom() { return this.nom; public void setCognom(String cognom) { public String getCognom() { return this.cognom; public void setAnyNaixement(int anyNaixement) { public int getAnyNaixement() { return this.anyNaixement; La classe Persona

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>

Configuració del gestor de BD (i altres propietats) 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) 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>

Inserció d’instàncies package 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(); } Inserció d’instàncies

Consulta d’instàncies package 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(); Consulta d’instàncies

Modificació d’instàncies package 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(); Modificació d’instàncies 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

Esborrat d’instàncies package 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(); Esborrat d’instàncies

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

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"); Agregacions "select avg(p.pes), sum(p.pes), max(p.pes), count(p) from Persona p");

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

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

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

Millorant l’estructura package 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;

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

public void esborra() { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); session.beginTransaction(); session.delete(this); session.getTransaction().commit(); HibernateUtil.getSessionFactory().close(); } public void actualitza() { session.update(this); public static java.util.List getLlistaPersones() { java.util.List persones = session.createQuery("from Persona").list(); return persones;

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

Un exemple més complet (amb herència i associacions) Persona Grup 0..* 0..* Empleat

Un per classe o un per tot el paquet Herència 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

<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"> <set name="persones" table="GRUP_PERSONA"> <key column="GRUP_ID"/> <many-to-many column="PERSONA_ID" class="Persona"/> </set> </hibernate-mapping>

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

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

Un empleat pertany a 1 departament, un departament té molts empleats 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’ ”

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

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

Arquitectura

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)