Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i...

122
1 Tecnologie Web T Metodologie di Progettazione della Persistenza: Approccio “forza bruta”, Pattern DAO, Framework ORM e Hibernate Home Page del corso: http://www-db.disi.unibo.it/courses/TW/ Versione elettronica: 4.02.MetodologieProgettazionePersistenza.pdf Versione elettronica: 4.02.MetodologieProgettazionePersistenza-2p.pdf DAO, ORM e Hibernate

Transcript of Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i...

Page 1: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

1

Tecnologie Web T

Metodologie di Progettazione della Persistenza: Approccio “forza bruta”, Pattern DAO,

Framework ORM e Hibernate

Home Page del corso: http://www-db.disi.unibo.it/courses/TW/ Versione elettronica: 4.02.MetodologieProgettazionePersistenza.pdf Versione elettronica: 4.02.MetodologieProgettazionePersistenza-2p.pdf

DAO, ORM e Hibernate

Page 2: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

2

Gestione della persistenza

Le nostre applicazioni sono sviluppate con linguaggi OO (lo stesso vale anche per i moderni sistemi informativi) mentre la persistenza dei dati è affidata ai DBMS relazionali OO: scalabilità e riusabilità RDBMS: affidabilità, efficienza, efficacia

Esistono differenze significative tra queste due tecnologie: differenze tecnologiche differenze culturali

Si parla di conflitto di impedenza

DAO, ORM e Hibernate

Page 3: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

3

Conflitto di impedenza (1/4)

Definito anche come “disaccoppiamento di impedenza” (o impedance mismatch) tra base di dati e linguaggio linguaggi: operazioni su singole variabili o oggetti SQL: operazioni su relazioni (insiemi di ennuple)

Differenze di accesso ai dati e correlazione: linguaggio: dipende dal paradigma e dai tipi

disponibili; ad esempio scansione di liste o “navigazione” tra oggetti

SQL: join (ottimizzabile)

DAO, ORM e Hibernate

Page 4: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

4

Conflitto di impedenza (2/4)

Differenze sui tipi di dato primitivi: linguaggi: numeri, stringhe, booleani SQL: CHAR, VARCHAR, DATE, ...

Differenze sui costruttori di tipo: linguaggio: dipende dal paradigma SQL: relazioni e ennuple

OID (trasparenti al programmatore) vs. chiavi primarie (visibili e manipolabili)

Riferimenti vs. chiavi esterne Ereditarietà (senza controparte nel mondo relazionale)

DAO, ORM e Hibernate

Page 5: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

5

Conflitto di impedenza (3/4)

In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da oggetti

Dal modello concettuale si può derivare (una prima versione di) classi che implementano la logica applicativa

(diciamo che queste classi implementano il modello di dominio, o più semplicemente il modello)

classi facade che offrono le operazioni (metodi) dell’applicazione

schema relazionale per memorizzare i dati questa attività può essere fatta anche successivamente in alcuni casi (sistemi legacy) il database potrebbe esistere

già e potrebbe non essere modificabile • quindi tutte le attività di progetto sono condizionate da questo

vincolo

DAO, ORM e Hibernate

Page 6: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

6

Conflitto di impedenza (4/4)

I dati sono memorizzati in maniera persistente nel DB A seconda del punto di vista (sviluppatore OO vs. DB Administrator - DBA) “Gli oggetti in memoria possono essere visti come

una copia di una porzione del database” “Il database può essere visto come un supporto su

cui memorizzare in maniera persistente i dati del modello”

Il conflitto di impedenza investe anche aspetti "culturali"

DAO, ORM e Hibernate

Page 7: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

7

Metodologie per la gestione della persistenza

In generale possiamo pensare che le operazioni (metodi) degli oggetti facade caricano tuple dalla base di dati e le usano per

creare gli oggetti del modello effettuano le operazioni della logica applicativa

(es. evadi ordine) salvano in maniera persistente gli oggetti del

modello nella base di dati L'interazione con il DB è una operazione critica:

esistono diverse metodologie (di complessità crescente) per realizzare questa interazione forza bruta pattern DAO framework ORM (e in particolare per noi Hibernate)

DAO, ORM e Hibernate

Page 8: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

8

Forza bruta

È la tecnica più semplice per gestire la persistenza forte accoppiamento con la sorgente dati

Consiste nello scrivere dentro le classi del modello un insieme di metodi che implementano le operazioni CRUD

Operazioni CRUD Create: inserimento di una tupla (che rappresenta un oggetto)

nel database (INSERT) Retrieve: ricerca di una tupla secondo un qualche criterio di

ricerca (SELECT) Update: aggiornamento di una tupla nel database (UPDATE) Delete: eliminazione di una tupla nel database (DELETE)

Ci possono essere diverse operazioni di Retrieve diversi criteri: “per chiave” vs. “per attributo” (es. ricerca

cliente per codice, per nome, etc.) diversi risultati (un oggetto, una collezione di oggetti) a seconda

del criterio

DAO, ORM e Hibernate

Page 9: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

9

Forza bruta in sintesi (1/2)

Per ogni classe MyC che rappresenta una entità del dominio, si definiscono: un metodo doRetrieveByKey(X key) che restituisce un oggetto istanza di MyC i cui dati sono

letti dal database • tipicamente da una tabella che è stata derivata dalla

stessa classe del modello di dominio che ha dato origine a MyC

recupera i dati per chiave

un metodo saveOrUpdate(…) che salva i dati dell'oggetto corrente nel database il metodo esegue una istruzione SQL update o insert

a seconda che l'oggetto corrente esista già o meno nel database

DAO, ORM e Hibernate

Page 10: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

10

Forza bruta in sintesi (2/2)

uno o più metodi doRetrieveByCond(…) che restituiscono una collezione di oggetti istanza della classe MyC che soddisfano una qualche condizione (basata sui parametri del metodo)

un metodo doDelete(…) che cancella dal database i dati dell'oggetto corrente

DAO, ORM e Hibernate

Page 11: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

11

Il pattern Data Access Object

La soluzione Forza bruta non è particolarmente conveniente L'accoppiamento tra la sorgente dati e le classi del

modello è molto forte Le classi del modello sono poco coese

(responsabilità eterogenee) Molto difficile iniziare a sviluppare senza

preoccuparsi di tanti (troppi !) dettagli e senza un ambiente operativo complesso (java + dbms)

Una soluzione "naturale" è quella di affidare le responsabilità di interagire con il database ad opportune classi

Questo è l'approccio suggerito dal pattern Data Access Object (DAO)

DAO, ORM e Hibernate

Page 12: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

12

Il pattern DAO

Un pattern è un “modo di fare le cose” che si è dimostrato efficace e che per questo si tende ad applicare di nuovo

Il pattern DAO è uno degli standard “J2EE design patterns”; rappresenta un possibile modo di separare: logica di business (es: Servlet, JSP, …) logica di persistenza (es: r/w su DB, …)

Infatti, i componenti della logica di business non dovrebbero mai contenere codice che accede direttamente al database! scarsa manutenibilità sovrapposizione di responsabilità

Solo gli oggetti previsti dal pattern DAO hanno il permesso di “vedere” il DB espongono metodi di accesso per tutti gli altri componenti

DAO, ORM e Hibernate

Page 13: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

13

DAO: Caratteristiche principali (1/2)

I valori scambiati tra DB e il resto dell’applicazione sono racchiusi in oggetti detti Data Transfer Object (DTO): campi privati per contenere i dati da

leggere/scrivere su db metodi getter e setter per accedere dall’esterno a

tali campi metodi di utilità (confronto, stampa, …)

Le operazioni che coinvolgono tali oggetti sono raggruppati in interfacce che definiscono i Data Access Object (DAO) disponibili: metodi CRUD altri metodi

DAO, ORM e Hibernate

Page 14: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

14

DAO: Caratteristiche principali (2/2)

Le implementazioni di tali interfacce (spesso indicate come oggetti DAO, per brevità) permettono l’effettivo accesso al database diverse implementazione possono permettere (e

rendere uniforme) l'accesso a DB di diversi vendor anche se si fa uso di un solo database, tale

separazione migliora comunque la divisione delle responsabilità tra le parti dell’applicazione

diventa facile migrare l’applicazione su DB diversi Gli oggetti DAO non sono istanziati direttamente dai

componenti, ma: possono essere ottenuti attraverso metodi factory

DAO, ORM e Hibernate

Page 15: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

15

Pattern DAO con classi Factory

Una unica factory astratta fornisce specifiche per le factory concrete espone un metodo creazionale parametrico per

ottenere factory concrete Una factory concreta per ogni tipo di DB supportato permette di ottenere oggetti DAO appropriati al

corrispondente tipo di DB può gestire aspetti quali ottenimento della

connessione, autenticazione, ... Un oggetto DTO per ogni tipo di entità che si vuole

rappresentare Una interfaccia DAO per ogni oggetto DTO Una implementazione dell'interfaccia DAO di un DTO

per ciascun DB supportato DAO, ORM e Hibernate

Page 16: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

16

Pattern DAO con classi Factory

DAO, ORM e Hibernate

Page 17: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

17

Pattern DAO: Struttura

DAO, ORM e Hibernate

Page 18: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

18

Pattern DAO con classi Factory: Diagramma di sequenza

DAO, ORM e Hibernate

Page 19: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

19

Pattern DAO: Diagramma di sequenza

DAO, ORM e Hibernate

Page 20: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

20

DAO in pratica

Per ogni classe Entità del modello di dominio creiamo (in un opportuno package) una interfaccia DAOEntità con (le signature dei) metodi che realizzano le operazioni CRUD

Queste interface sono implementate da classi (organizzate in opportuni package) questa scomposizione permette maggiore

flessibilità

DAO, ORM e Hibernate

Page 21: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

21

Caso di studio (UML)

Prodotto

CodiceProdotto

Nome

Descrizione

Costo

Ordine

CodiceOrdine

Data

stato

Cliente

CodiceCliente

Nome

Indirizzo

RigaOrdine

Quantità

NumeroLinea

* *

*

1

1 1

DAO, ORM e Hibernate

Page 22: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

22

Esempio: ProdottoDAO

public interface ProdottoDAO { public List<Prodotto> doRetrieveAll() throws PersistenceException; public Prodotto doRetriveByKey(String codice) throws PersistenceException; public void saveOrUpdate(Prodotto prodotto) throws PersistenceException; public void delete(Prodotto prodotto) throws PersistenceException; // eventuali altri doRetriveBy... }

DAO, ORM e Hibernate

Page 23: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

23

Esempio: ProdottoDAOImpl

public class ProdottoDAOImpl implements ProdottoDAO { public List<Prodotto> doRetrieveAll() throws PersistenceException { Connection connection = null; List<Prodotto> prodotti; … try { … } catch (SQLException sqle) { throw new PersistenceException(sqle); } finally { … } return prodotti; } … }

DAO, ORM e Hibernate

Page 24: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

24

Interazione Facade-DAO: Esempio

ProdottoDAO

ProdottoDB2DAO DB2

Prodotto

Facade

DAO, ORM e Hibernate

Page 25: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

25

Mettiamo ordine al codice

Abbiamo classi per il modello, classi per la persistenza, classi di utilità classi del modello nel package modello interfacce DAO nel package persistenza

implementazioni (dbms dependant) dei DAO in package persistenza.db2

classi di utilità nel package util

DAO, ORM e Hibernate

Page 26: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

26

Nota terminologica

Le classi del modello implementano le entità del modello concettuale, ed è bene che rispettino le seguenti convenzioni: tutte le proprietà devono essere private per ogni proprietà: metodi setter e getter pubblici costruttore no-arg visibile

Una classe che rispetta queste convenzioni viene chiamata java bean

Rispetto al nostro caso di studio, le nostre classi Cliente, Prodotto, Ordine, RigaOrdine sono bean

DAO, ORM e Hibernate

Page 27: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

27

Caso di studio

ORM e Hibernate

package modello; import java.util.*; import persistenza.*; public class FacadeImpl implements Facade { private ClienteDAO clienteDao; …. public FacadeImpl() { clienteDao = new ClienteDAOImpl(); } public void inserisciClienteNellaAnagrafica(Cliente cliente) throws ClienteException { try { clienteDao.saveOrUpdate(cliente); } catch (PersistenceException e) { throw new ClienteException("Exception in ClientiFacade while creating cliente."); } } public List<Cliente> anagraficaClienti(){ try { return clienteDao.doRetrieveClienteAll(); } catch (PersistenceException e) { throw new ClienteException("Exception in ClientiFacade while retrieving cliente.", e); } } public Cliente trovaClientePerCodice(String codiceCliente){ try { return clienteDao.doRetrieveClienteByCodice(codiceCliente); } catch (PersistenceException e) { throw new ClienteException("Exception in ClientiFacade while retrieving cliente"+ codiceCliente +, e); } } … }

Page 28: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

28

Soluzioni al conflitto di impedenza

Analizziamo ora i principali problemi dovuti al conflitto di impedenza e ne presentiamo le soluzioni

A scopo didattico lavoriamo su DAO, ma le considerazioni che facciamo seguendo questa soluzione hanno validità generale!!

Al termine del trattamento generale delle problematiche relative al conflitto di impedenza, concluderemo la gestione della persistenza illustrando la metodologia Object Relational Mapping (ORM) e una sua diretta implementazione, ovvero il framework Hibernate

DAO, ORM e Hibernate

Page 29: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

29

Risolvere il conflitto di impedenza

Nel modello OO, le relazioni tra oggetti sono realizzate con riferimenti, mentre nel modello relazionale sono realizzate con i valori

Vediamo problemi e soluzioni relativamente a: Retrieve: dal DB agli oggetti

(ricostruzione degli oggetti a partire da dati persistenti)

Create: dagli oggetti al DB (memorizzazione persistente degli oggetti nel DB)

DAO, ORM e Hibernate

Page 30: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

30

Retrieve: Ricostruzione degli oggetti dal DB

Il problema principale nel ricostruire oggetti a partire dalla base di dati consiste nel ricostruire i riferimenti

Forze in gioco chiavi esterne contro riferimenti join (operazione "non direzionale") contro

navigazioni

DAO, ORM e Hibernate

Page 31: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

31

Caso di studio

Prodotto CodiceProdotto

Nome

Descrizione

Costo

Ordine CodiceOrdine

Data

stato

Cliente CodiceCliente

Nome

Indirizzo

RigaOrdine Quantità

NumeroLinea

* *

*

1

1 1

DAO, ORM e Hibernate

Page 32: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

32

Ricostruzione degli oggetti dal DB

Consideriamo la ricostruzione di un oggetto Ordine, ad esempio, per definire il metodo Ordine doRetrieveOrdineByKey(String codice) nella classe Ordine:

una collezione di riferimenti a oggetti RigaOrdine • ogni riga ordine ha un riferimento ad un oggetto Prodotto

un riferimento ad un oggetto della classe Cliente

nel database: tabella ORDINI (ha una foreign key (FK) con CLIENTI) tabella RIGHEORDINE (FK con ORDINI, FK con PRODOTTI) tabella CLIENTI

Per ricostruire un oggetto Ordine "completo" devo ricostruire la collezione di oggetti RigaOrdine e l'oggetto Cliente (e anche questi oggetti devono essere "completi"?!)

DAO, ORM e Hibernate

Page 33: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

33

Ricostruzione degli oggetti dal DB

Per ora, a fini didattici, non preoccupiamoci del riferimento Cliente: successivamente ci preoccupiamo anche di questo

Come ricostruiamo l'oggetto Ordine? eseguo un join tra le tabelle ORDINI e RIGHEORDINE

itero sul ResultSet e costruisco i vari oggetti Ordine e RigaOrdine opportunamente collegati

DAO, ORM e Hibernate

Page 34: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

34

Nota

Eseguo un join tra le tabelle ORDINI e RIGHEORDINE Che join usiamo? è possibile che nella tabella ORDINI ci siano tuple

per le quali non ci sono righe nella tabella RIGHE_ORDINE?

se la risposta è SI, allora devo usare un outer join

DAO, ORM e Hibernate

Page 35: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

35

Un inciso

Potrebbe sembrare più semplice evitare di effettuare un join, usando due SELECT e gestendone i risultati nel codice Java: cerco nella tabella ORDINI del database l'ordine con l'id

richiesto e costruisco un oggetto Ordine cerco nella tabella RIGHEORDINE del database le tuple

che hanno come chiave esterna l'id dell'oggetto Ordine del punto precedente e con esse costruisco una collezione di oggetti RigaOrdine

aggiungo la collezione di righe ordine all'oggetto Ordine

Commenti: (apparentemente) il codice per costruire l'oggetto Ordine è più semplice (ma se sapete usare le collezioni il problema non si pone più di tanto…)

ma i DBMS sono ottimizzati per effettuare efficientemente join!

DAO, ORM e Hibernate

Page 36: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

36

Ricostruzione degli oggetti dal DB

Ma che cosa è un "oggetto completo"? con un modello di dominio complesso questa

strategia può portarci a caricare una rete molto vasta di oggetti

esempio: ClienteOrdineRigaOrdineProdottoFornitore

Fino a quando devo costruire oggetti "inseguendo i riferimenti” ?

DAO, ORM e Hibernate

Page 37: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

37

Ricostruzione degli oggetti dal DB

Possiamo dare una risposta a queste domande analizzando i casi d'uso e il modello del dominio In particolare l'inseguimento dei riferimenti tra

oggetti è guidato dalle operazioni offerte dal sistema

Nel progettare le classi, i riferimenti vanno messi considerando la direzione in cui le corrispondenti associazioni sono navigate dalle operazioni del sistema

! questo aspetto non ha rilevanza nella progettazione del database, perché i riferimenti sono implementati tramite valori e l'operatore di join non è direzionale

DAO, ORM e Hibernate

Page 38: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

38

Ricostruzione degli oggetti dal DB

E quando non ha senso costruire un oggetto completo, come mi comporto? i metodi che richiedono l'inseguimento di un riferimento,

se invocati devono restituire l'oggetto corretto!

• In questo caso ricorriamo ad una tecnica, detta Caricamento Pigro, implementata tramite l'applicazione del Pattern Proxy

DAO, ORM e Hibernate

Page 39: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

39

Lazy Load (caricamento pigro)

Consideriamo la classe Cliente: l'associazione con l'Ordine è bidirezionale

Tuttavia non è ragionevole pensare che per caricare i dati di un cliente si debba ricostruire l'intera rete di oggetti (fino a Prodotto!?)

Possiamo pensare che gli ordini associati al cliente possano essere caricati solo quando richiesti: quando invochiamo il metodo getOrdini() su un

oggetto Cliente Questa strategia si chiama Lazy Load (caricamento

pigro)

DAO, ORM e Hibernate

Page 40: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

40

Lazy Load (caricamento pigro)

In pratica quello che vogliamo fare è caricare i dati solo quando questi sono effettivamente richiesti

Vediamo come dovrebbe agire il metodo getOrdini() della classe Cliente seguendo questa strategia quando invocato per la prima volta, il metodo getOrdini()

esegue la query per costruire gli oggetti Ordine associati al cliente, aggiunge i riferimenti a questi oggetti nella collezione dell'oggetto Cliente, e restituisce la collezione

È importante osservare che se il metodo non viene mai invocato, il costo di caricare i dati relativi agli ordini non viene mai pagato

Se decidiamo di implementare questa strategia nella classe Cliente mettiamo codice di gestione della persistenza in una classe del dominio se in futuro vogliamo cambiare strategia?

Per implementare bene la strategia Lazy Load senza ridurre la coesione nella classe del modello è utile fare riferimento al pattern Proxy

DAO, ORM e Hibernate

Page 41: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

41

Lazy Load e classi proxy

Le classi xxxDAOImpl non restituiscono un bean “completo” ma un proxy Il proxy ha il compito di gestire il caricamento degli

oggetti collegati Il proxy deve contenere tutte le informazioni

necessarie per effettuare il caricamento “lazy” Gli oggetti collegati vengono caricati solo su

richiesta Il proxy “simula” il comportamento del bean

DAO, ORM e Hibernate

Page 42: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

42

Lazy Load: Dettagli

Quando le classi xxxDAOImpl ricevono una richiesta viene eseguita una query sul DB, istanziato e restituito un oggetto del tipo richiesto

L’oggetto istanziato non è di tipo xxxBean, ma xxxProxy

La classe xxxProxy estende la corrispondente xxxBean e riscrive i metodi che devono implementare le operazioni onerose

Vediamo un esempio…

DAO, ORM e Hibernate

Page 43: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

43

Lazy Load: Implementazione con proxy public class Cliente { private int codiceCliente; private List<Ordine> ordini; … public List<Ordine> getOrdini() { return this.ordini; } ... } public class ClienteProxy extends Cliente { public List<Ordine> getOrdini() { List<Ordine> listaOrdini = null; try { OrdineDAO daoOrdine = new OrdineDAOImpl(); listaOrdini = daoOrdine.doRetrieveByCliente(this.getCodice()); this.setOrdini(listaOrdini); } catch (PersistenceException e) { throw new UnChechedPersistenceException(e.getMessage()); } return listaOrdini; } }

DAO, ORM e Hibernate

Page 44: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

44

Lazy Load: Implementazione con proxy (e caching) public class Cliente { private int codiceCliente; private List<Ordine> ordini; … public List<Ordine> getOrdini() { return this.ordini; } ... } public class ClienteProxy extends Cliente { private boolean caricato = false; public List<Ordine> getOrdini() { try { if (!this.caricato) { OrdineDAO dao = new OrdineDAOImpl(); this.setOrdini(dao.doRetrieveByCliente(this.getCodice())); this.caricato = true; } } catch (PersistenceException e) { throw new UnChechedPersistenceException(e.getMessage()); } return super.getOrdini(); } }

DAO, ORM e Hibernate

Page 45: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

45

Lazy Load: Osservazioni

Quando uso il "caricamento pigro" ? Dipende dai casi d’uso definiti in fase di progettazione Ordine e RigaOrdine Esistono casi d’uso che prevedono l’uso

dell’intestazione dell’ordine ma non del dettaglio delle righe?

RigaOrdine e Prodotto Esistono casi d’uso che prevedono l’uso di una o più

riga senza il dettaglio del prodotto?

etc.

DAO, ORM e Hibernate

Page 46: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

46

Lazy Load: Organizzazione del codice

Organizzazione del codice: I Proxy appartengono al package della persistenza

(in particolare, al package con le implementazioni dei DAO)

DAO, ORM e Hibernate

Page 47: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

47

Ricostruzione degli oggetti dal DB Concludiamo ora la scrittura del codice per la classe OrdineDAO In particolare supponiamo di voler effettuare un caricamento

pigro del cliente associato all'ordine

public class OrdineProxy extends Ordine { private Cliente cliente; … public Cliente getCliente() throws DAOException {

if (cliente==null) { String query = "select * from clienti " + "where clienti.codice = ?"; …

} return cliente; }

C'è un problema: non abbiamo il codice cliente! Coerentemente

con l'approccio OO nella classe abbiamo un riferimento ad un oggetto Cliente

Questo dato è presente nella tabella ORDINI (chiave esterna), e quando abbiamo caricato l'ordine questo valore non è stato salvato in nessuna variabile!!

DAO, ORM e Hibernate

public class OrdineProxy extends Ordine { private Cliente cliente; … public Cliente getCliente() throws DAOException { if (cliente==null) { String query = "select * from clienti " + "where clienti.codice = ?"; … } return cliente; }

Page 48: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

48

Ricostruzione degli oggetti dal DB Siamo costretti ad eseguire un join (ci sarebbe bastata una

selezione)

public class OrdineProxy extends Ordine { private Cliente cliente; … public Cliente getCliente() {

if (cliente==null) { String query = "select * from ordini join clienti on ordini.id = clienti.idordine" where ordini.id = ?"; // codice per l'esecuzione della query // con i dati ritornati viene costruito l'oggetto Cliente

} return cliente;

} }

Il problema sussiste anche nella classe Cliente? Perchè?

DAO, ORM e Hibernate

public class OrdineProxy extends Ordine { private Cliente cliente; … public Cliente getCliente() { if (cliente==null) { String query = "select * from ordini join clienti on " + "ordini.idcliente = clienti.id where ordini.id = ?"; // codice per l'esecuzione della query // con i dati restituiti viene costruito l'obj Cliente … } return cliente; } }

Page 49: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

49

Ricostruzione degli oggetti dal DB

Il problema sorge quando navighiamo una relationship uno-a-molti o uno-a-uno seguendo il vincolo di integrità referenziale (la chiave esterna)

Per risolvere questo problema dobbiamo effettuare un join (al posto di una semplice selezione)

DAO, ORM e Hibernate

Page 50: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

50

Ricostruzione degli oggetti dal DB

Possiamo sintetizzare il processo di ricostruzione degli oggetti dal DB come segue: in base ai casi d'uso (e a una stima della frequenza

delle corrispondenti operazioni) decidiamo quando conviene seguire una strategia Lazy Load

per le classi con associazioni per le quali è stata scelta la strategia Lazy Load applichiamo il pattern Proxy

per le classi con associazioni per le quali non conviene applicare la strategia Lazy Load ricostruiamo la rete (parziale) di oggetti con i risultati di un join

In fase di progettazione conviene quindi arricchire il class diagram con annotazioni sulle associazioni che indicano la strategia di caricamento ("fetch") dei dati: pigro (Lazy Load) vs. immediato (Eager)

DAO, ORM e Hibernate

Page 51: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

51

Caso di studio

Prodotto CodiceProdotto

Nome

Descrizione

Costo

Ordine CodiceOrdine

Data

stato

Cliente CodiceCliente

Nome

Indirizzo

RigaOrdine Quantità

NumeroLinea

* *

*

1

1 1

fetch: lazy-load

fetch: eager fetch: lazy-load

fetch: eager

DAO, ORM e Hibernate

Page 52: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

52

Risolvere il conflitto di impedenza

Nel modello OO, le relazioni tra oggetti sono realizzate con riferimenti, mentre nel modello relazionale sono realizzate con i valori

Vediamo problemi e soluzioni relativamente a: Retrieve: dal DB agli oggetti

(ricostruzione degli oggetti a partire da dati persistenti)

Create: dagli oggetti al DB (memorizzazione persistente degli oggetti nel DB)

DAO, ORM e Hibernate

Page 53: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

53

Create: Rendere persistenti gli oggetti

L'operazione di CREATE ha lo scopo di rendere persistenti gli oggetti della applicazione

Problemi persistenza dei riferimenti propagazione degli aggiornamenti

DAO, ORM e Hibernate

Page 54: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

54

Persistenza dei riferimenti

Come rendiamo persistenti i riferimenti? se il dominio offre identificatori naturali per tutte le

entità il problema è limitato (ma potremmo fare considerazioni su prestazioni e portabilità)

se non tutte le classi hanno identificatori naturali ("semplici") è utile introdurre chiavi surrogate

In generale è sconveniente usare un approccio ibrido (chiavi surrogate e identificatori naturali)

Di conseguenza, quando possibile*, è consigliato usare sempre chiavi surrogate tutte le tabelle corrispondenti a entità del dominio

hanno una chiave id di tipo intero tutte le classi hanno una variabile di istanza id di

tipo intero

* Potrebbe non essere possibile nel caso di applicazioni costruite su DB già esistenti

DAO, ORM e Hibernate

Page 55: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

55

Persistenza dei riferimenti

Chiavi surrogate la chiave può essere vista come una

rappresentazione persistente dell'OID in parte cerchiamo di avvicinare i due mondi

(relazionale ed oggetti) senza stravolgerli, armonizzando le differenze

Questa soluzione offre vantaggi in termini di prestazioni (usando come chiavi degli interi) portabilità ed evoluzione (gli identificatori naturali

possono cambiare nel tempo*) *Esempio: è allo studio una revisione del codice fiscale

DAO, ORM e Hibernate

Page 56: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

56

Persistenza dei riferimenti

Che cosa deve fare una operazione di Create se l'oggetto non esiste nel DB l'operazione di Create

deve eseguire una insert nel DB dei dati gestiti da un oggetto del modello

Se nel DB usiamo chiavi surrogate, come le gestiamo? è opportuno avere una rappresentazione della

chiave anche nel modello ad oggetti quindi ad ogni entità associamo esplicitamente una

variabile di istanza id (di tipo int)

DAO, ORM e Hibernate

Page 57: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

57

Persistenza dei riferimenti

Chi ci dà il valore di una chiave surrogata? la chiave viene creata al momento dell'inserimento

di un oggetto nel DB Diverse soluzioni:

soluzione naive: chiedo al DB il valore massimo, lo incremento ed eseguo l'inserimento usando tale valore

uso campi auto-incrementanti: occorre aggiornare il valore della variabile id nell'oggetto, ovvero dopo l'inserimento, dobbiamo interrogare il DB per riottenere tale valore

uso una sequenza SQL che interrogo per farmi dare un nuovo id prima di ogni inserimento efficiente (il DBMS offre anche funzionalità di caching) semplice da implementare qualche limite di portabilità (nonostante le sequenze siano

standard SQL, i vari DBMS differiscono un po' nell'uso di questo costrutto)

DAO, ORM e Hibernate

Page 58: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

58

Persistenza dei riferimenti

Affidiamo la responsabilità della gestione degli id ad una classe opportuna, che chiamiamo IdBroker

Al solito, per favorire la portabilità possiamo definire una interfaccia IdBroker, le cui implementazioni sono DBMS-dependant

DAO, ORM e Hibernate

Page 59: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

59

IdBroker: Esempio

DAO, ORM e Hibernate

package persistenza.db2; import java.sql.*; import persistenza.*; public class IdBrokerDB2 implements IdBroker { public int newId() throws PersistenceException { int newId = -1; DataSource ds = new DataSource(); ResultSet result = null; PreparedStatement statement = null; Connection connection = null; try { connection = ds.getConnection(); String sqlQuery = "SELECT(NEXTVAL FOR sequenza_id) INTO newId"; statement = connection.prepareStatement(sqlQuery); result = statement.executeQuery(); if (result.next()) newId = result.getInt("newId"); else throw new PersistenceException("invalid id"); } catch(SQLException e) { throw new PersistenceException(e.getMessage()); } finally { try { if (statement != null) statement.close(); if (connection!= null) connection.close(); } catch (SQLException e) { throw new PersistenceException(e.getMessage()); } } return newId; } }

Page 60: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

60

Persistenza dei riferimenti: Esempio

DAO, ORM e Hibernate

public class ProdottoDAODB2 { private void insert(Prodotto prodotto, Connection connection) throws PersistenceException { PreparedStatement statement = null; IdBroker idBroker = new IdBrokerDB2(); try { prodotto.setId(idBroker.newId()); String insert = "insert into prodotti(codice_prodotto, nome, descrizione, disponibilita, prezzo, id) values (?,?,?,?,?,?)"; statement = connection.prepareStatement(insert); statement.setInt(1, prodotto.getCodiceProdotto()); statement.setString(2, prodotto.getNome()); statement.setString(3, prodotto.getDescrizione()); statement.setInt(4, prodotto.getDisponibilita()); statement.setInt(5, prodotto.getPrezzo()); statement.setInt(6, prodotto.getId()); statement.executeUpdate(); } catch (SQLException e) { throw new PersistenceException(e.getMessage()); } finally { try { if (statement != null) statement.close(); if (connection!= null) connection.close(); } catch (SQLException e) { throw new PersistenceException(e.getMessage()); } } } … }

Page 61: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

61

Sequenze SQL

Statement SQL (DB2) per la creazione della sequenza: CREATE SEQUENCE sequenza_id AS INTEGER START WITH 1 INCREMENT BY 1 MINVALUE 0 MAXVALUE 9999999 NO CYCLE;

DAO, ORM e Hibernate

Page 62: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

62

Propagazione degli aggiornamenti

Quando effettuiamo una operazione di create (ma analogamente update o delete) propaghiamo gli aggiornamenti a tutta la rete di oggetti ?

Ad esempio, consideriamo la classe Ordine: quando salviamo i dati di un ordine, salviamo anche

i dati di tutti gli oggetti RigaOrdine e Cliente ad esso associato?

Anche in questo caso dipende dai casi d'uso

DAO, ORM e Hibernate

Page 63: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

63

Progettazione della persistenza

Facendo riferimento al class diagram, su tutte le associazioni indichiamo: la cardinalità il verso secondo cui l'applicazione naviga la

associazione la strategia di fetch: Lazy Load vs. Eager (associata al verso)

la strategia di propagazione degli aggiornamenti: Cascade vs. No cascade (associata al verso)

DAO, ORM e Hibernate

Page 64: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

64

Caso di studio

Prodotto CodiceProdotto

Nome

Descrizione

Costo

Ordine CodiceOrdine

Data

stato

Cliente CodiceCliente

Nome

Indirizzo

RigaOrdine Quantità

NumeroLinea

* *

*

1

1 1

fetch: lazy-load cascade: none

fetch: eager cascade: persist, delete

fetch: lazy-load cascade: none

fetch: eager cascade: none

DAO, ORM e Hibernate

Page 65: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

65

Object Relational Mapping

DAO, ORM e Hibernate

È tempo di riprendere e concludere il trattamento delle metodologie alternative a “forza burta” e DAO per la realizzazione del layer di persistenza, ovvero di trattare la tecnica Object Relational Mapping (ORM, O/RM oppure O/R mapping) Aumenta il livello di astrazione (semplicità di utilizzo

per lo sviluppatore e diminuzione della quantità di codice che occorre scrivere)

Aumenta la complessità (diminuzione delle performance)

ORM è “la persistenza automatica (e trasparente) di oggetti di applicazioni Java in tabelle di un DB relazionale, basata su metadati che descrivono il mapping tra oggetti e DB”

Page 66: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

66

ORM in sintesi (1/3)

Lavora trasformando (in modo reversibile) i dati da una rappresentazione all’altra; ciò implica alcune penalizzazioni in termini di performance tuttavia se ORM è implementato come “middleware”

esistono diverse opportunità di ottimizzazione non possibili per un livello di persistenza “hand-coded ” (à la JDBC)

La fornitura e la gestione dei metadati che governano la trasformazione aggiungono overead al tempo di sviluppo tuttavia tale costo è inferiore o equivalente al costo

che comporta il mantenimento di una soluzione “hand-coded ”

DAO, ORM e Hibernate

Page 67: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

67

ORM in sintesi (2/3)

Una soluzione ORM consiste di quattro componenti: Una API per eseguire le operazioni CRUD sugli

oggetti delle classi del modello Un linguaggio o una API per specificare query che

fanno riferimento alle classi e alle proprietà delle classi

Uno strumento per la specifica del mapping mediante metadata

Una tecnica per l’implementazione di ORM per interagire con oggetti transazionali al fine di eseguire funzioni di ottimizzazione quali, ad esempio, lazy load fetching e dirty checking

DAO, ORM e Hibernate

Page 68: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

68

ORM in sintesi (3/3)

Usiamo il termine full ORM per includere ogni livello di persistenza in cui SQL è automaticamente generato da una descrizione basata su metadati

L’applicazione interagisce con le API ORM e le classi del modello di dominio ed astrae dal livello SQL/JDBC sottostante

Supporta object modeling sofisticati, quali composizione, ereditarietà, polimorfismo e persistenza attraverso raggiungibilità

Un certo numero di tool commerciali e open source Java ORM hanno raggiunto questo livello di qualità Hibernate è un tool full ORM

l’API di Hibernate è nativa e progetta dagli sviluppatori Hibernate

DAO, ORM e Hibernate

Page 69: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

69

Perché ORM e Hibernate?

Tra i benefici di ORM e Hibernate Produttività: il codice dedicato alla gestione della persistenza

di una applicazione Java è il più “tedioso”; Hibernate elimina la maggior parte di questo duro lavoro permettendo di concentrare l’attenzione su problemi di businnes logic

Manutenibilità: poche linee di codice rendono il sistema più comprensibile perché esso enfatizza aspetti di businnes logic rispetto a dettagli implementativi; più importante, un sistema con meno linee di codice è più facile per il refactor

Performance: una comune affermazione è che la persistenza hand-coded è sempre più performante rispetto a quella automatizzata; occorre però considerare anche aspetti di tempo e budget per la realizzazione della stessa

Indipendenza dal vendor: ORM astrae una applicazione dal DB sottostante e dal dialetto SQL; se un tool ORM supporta un certo numero di DB (e la maggior parte lo fa) ciò conferisce portabilità alla applicazioni

DAO, ORM e Hibernate

Page 70: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

70

Perché Hibernate e non DAO?

Per lo sviluppatore la metodologia DAO può risultare onerosa (e “noiosa”), in termini di scrittura di codice, e dipendente dal data source Inoltre persistenza e transazionalità sono gestite a

livello di programmazione La metodologia Hibernate rappresenta una soluzione

standard per riuscire a implementare persistenza e transazionalità velocemente e senza preoccuparsi dei dettagli del data source sottostante; esempio:

DAO, ORM e Hibernate

… Session session = HibernateUtil.getSessionFactory().openSession(); User user = new User("pippo"); String userId = (String) session.save(user); …

Page 71: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

71

Il framework Hibernate

Rappresenta lo standard risolutivo per il mapping object/relational automatico tra oggetti Java e relazioni del DB

Tale mapping si può realizzare per mezzo di descrittori XML specifici di Hibernate (soluzione di

riferimento per noi) o, in alterantiva, di annotazioni Java conformi allo

standard JPA Il framework Hibernate si “appoggia” e sfrutta le

tecnologie SQL e JDBC ecco perché è stato coisì importante apprendere

prima JDBC!

DAO, ORM e Hibernate

Page 72: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

72

Un po’ di storia

Il progetto relativo a Hibernate è stato promosso nel 2001 da Gavin King come alternativa all’uso di entity bean à la EJB2 scopo principale quello di offrire migliori capacità nella

gestione della persistenza semplificando tutte le complessità

All’inizio del 2003, il gruppo di sviluppo Hibernate ha avviato la realizzazione della release Hibernate 2 che offre miglioramenti significativi rispetto alla prima versione

Dal 2010 la versione di riferimento è Hibernate 3.x Hibernate 3 (dalla versione 3.5.0 in su) rappresenta

l’implementazione certificata (standard) delle specifiche API Java Persistence, versione 2.0

Ultima versione (febbraio 2017) Hibernate 5.2.10

DAO, ORM e Hibernate

Page 73: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

73

Hibernate Core

Anche noto come Hibernate o Hibernate 3.x Software open source e free, distribuito sotto licenza

GNU Libreria ORM per Java: servizio di base per la gestione

della persistenza in applicazioni Java fornisce un framework per mappare un modello di

dominio object-oriented su di una base di dati relazionale

caratteristica primaria: mapping da classi Java a tabelle di una base di dati (e mapping da tipi di dati Java a tipi di dati SQL)

inoltre, fornisce l’abilità di interrogare la basi di dati

DAO, ORM e Hibernate

Page 74: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

74

Hibernate Core

Il codice della applicazione usa le API di Hibernate per gestire la persistenza

I mapping tra classi Java e tabelle relazionali sono specificati in appositi file XML

In linea di principio, lo sviluppatore è esonerato da: richieste di esecuzione di chiamate SQL gestione manuale dei risultati di chiamate SQL e loro

eventuale conversione in oggetti

L'applicazione rimane portabile in tutti i sistemi di gestione supportati, con pochissimo overhead

Può essere usato in maniera indipendente dal tipo di applicazione, di piattaforma e di ambiente runtime, con tutti i JDK

DAO, ORM e Hibernate

Page 75: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

75

Architettura Hibernate

L’architettura “completa” di Hibernate astrae dalle API JDBC/JTA sottostanti livello di applicazione può essere trasparente a

questi dettagli

DAO, ORM e Hibernate

Architettura di alto livello Architettura “completa”

Page 76: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

76

Principali oggetti dell’API Hibernate*

SessionFactory Session Persistent Objects Transient and Detached Object Transaction

N.B. Per ora ci basta pensare a una transazione come a una sequenza di operazioni che può concludersi con un successo o un insuccesso (unità atomica di elaborazione) ; affronteremo in modo approfondito la gestione delle transazioni a breve…

Connection Provider Transaction Factory

* http://docs.jboss.org/hibernate/core/3.5/api/ DAO, ORM e Hibernate

Page 77: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

77

SessionFactory

Classe org.hibernate.SessionFactory

Factory per oggetti Session e cliente di ConnectionProvider Una factory per ogni DB

Può mantenere una cache opzionale di secondo livello con dati riusabili in diverse transazioni

DAO, ORM e Hibernate

Page 78: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

78

Session

Classe org.hibernate.Session

Rappresenta un contesto di persistenza (wrapper a JDBC Connection) e la sua vita è delimitata dall’inizio e dalla fine di una transazione logica

Gestisce le operazioni del ciclo di vita degli oggetti persistenti

Fa da factory per oggetti Transaction Mantiene una cache (non modificabile) di primo livello

derivante dal mapping con il DB che viene utilizzata durante la navigazione degli oggetti

DAO, ORM e Hibernate

Page 79: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

79

Oggetti persistent

Oggetti single-threaded che contengono lo stato persistente e la logica di business Possono essere normali JavaBean devono essere associati esattamente a un

oggetto Session Modifiche fatte sugli oggetti persistenti sono

automaticamente propagate sulle tabelle DB (al loro “commitment ”)

Appena si chiude la sessione, gli stessi oggetti diventano “detached” e possono essere usati liberamente

DAO, ORM e Hibernate

Page 80: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

80

Oggetti transient e detached

Istanze di classi persistenti che non sono correntemente associati a nessuna Session

Possono essere stati istanziati dalla applicazione e non essere ancora diventati persistenti, oppure derivare da una Session chiusa

Modifiche fatte su questi oggetti non si riflettono sul DB

Operazioni di persist o merge per farli tornare “persistenti” (con modifiche correlate alle tabelle del DB)

DAO, ORM e Hibernate

Page 81: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

81

Transaction

Classe org.hibernate.Transaction

Oggetto single-threaded usato dalla applicazione per specificare unità atomiche di lavoro

Permette di astrarre dai dettagli dei sottostanti meccanismi transazionali (JDBC, JTA, …)

Un oggetto Session può essere coinvolto in diverse Transaction

La demarcazione delle transazioni non è opzionale: indipendentemente dall’utilizzare le API JDBC

sottostanti o Transaction, deve comunque essere sempre specificata in modo esplicito

DAO, ORM e Hibernate

Page 82: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

82

ConnectionProvider

Classe org.hibernate.connection.ConnectionProvider

Factory per un pool di connessioni JDBC. Astrae la applicazione dal Data Source o dal DriverManager sottostante

Non è esposta alla applicazione ma può essere estesa e/o implementata dallo sviluppatore

DAO, ORM e Hibernate

Page 83: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

83

TransactionFactory

Classe org.hibernate.TransactionFactory

Factory per oggetti Transaction Non è esposta alla applicazione ma può essere estesa

e/o implementata dallo sviluppatore

DAO, ORM e Hibernate

Page 84: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

84

Stato degli oggetti persistenti

Una istanza di una classe persistente può assumere in ogni istante uno fra tre stati possibili, definiti all’interno di un contesto di persistenza Transient non appartenente a un contesto di persistenza

Persistent appartenente a un contesto di persistenza

Detached usualmente appartenente a un contesto di

persistenza ma non in questo momento

DAO, ORM e Hibernate

Page 85: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

85

Stato transient

Istanza mai associata a una sessione (contesto di persistenza)

Non ha identità di persistenza (valore associato alla primary key)

Non ha righe corrispondenti nel DB

DAO, ORM e Hibernate

Page 86: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

86

Stato persistent

Istanza correntemente associata con una sessione (contesto di persistenza)

Ha una identità di persistenza (valore associato alla primary key) e usualmente una riga corrispondente in una tabella DB Ad es. quando un oggetto viene creato in una

sessione o un oggetto transient viene fatto diventare persistente

DAO, ORM e Hibernate

Page 87: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

87

Stato detached

Istanza che è stata associata a un contesto di persistenza in passato, ma quella sessione è stata chiusa oppure l’istanza è stata trasferita tramite serializzazione a un altro processo

Ha una identità di persistenza (valore associato alla primary key) e possibilmente una riga corrispondente in una tabella DB Ad es. quando un oggetto deve essere inviato ad un

altro processo, che lo utilizzerà senza necessità di avere un contesto di persistenza associato

DAO, ORM e Hibernate

Page 88: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

88

Il ciclo di vita degli oggetti persistenti

Una applicazione orientata agli oggetti che fa uso di un meccanismo di persistenza deve interagire con il servizio di persistenza ogni volta che ha bisogno di propagare lo stato di un oggetto in memoria sulla base di dati

Lo stato di un oggetto che appartiene ad una classe persistente cambia a seconda dell'operazione del servizio di persistenza che viene invocata

DAO, ORM e Hibernate

Page 89: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

89

Transizioni di stato Oggetti Transient possono diventare persistenti

tramite chiamate ai metodi save(), persist()o saveOrUpdate(), ovviamente dell’oggetto Session associato

Ogni istanza di oggetto persistente restituita da get()o load() è Persistent

Oggetti Persistent possono diventare transienti tramite l’invocazione di delete()

Oggetti Persistent possono diventare “staccati” mediante l’invocazione di evict(), clear()e close()

Oggetti Detached possono diventare persistenti tramite chiamate ai metodi update(), saveOrUpdate() e merge()(con istanziazione di un nuovo oggetto persistente)

DAO, ORM e Hibernate

Page 90: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

90

Hibernate Query Language

DAO, ORM e Hibernate

Hibernate fornisce un linguaggio di interrogazione ispirato a SQL chiamato Hibernate Query Language (HQL) Permette la scrittura di query SQL-like definite sui

data object Hibernate; esempi:

Sono inoltre supportate Criteria Queries come alternativa Object Oriented a HQL

Update a stock name to “DIALOG1″ where stock code is “7277″ Query query = session.createQuery("update Stock set stockName = :stockName" + " where stockCode = :stockCode"); query.setParameter("stockName", "DIALOG1"); query.setParameter("stockCode", "7277"); int result = query.executeUpdate();

Delete a stock where stock code is “7277″ Query query = session.createQuery("delete Stock where stockCode = '7277'"); int result = query.executeUpdate();

Page 91: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

91

Hibernate: Strategie di fetching

Una strategia di fetching determina come e quando i dati vengono effettivamente caricati dal DB per una applicazione che usa gli oggetti di persistenza associati La strategia adottata ha ovviamente impatto sulle

performance ottenibili ; di solito dichiarata in un file di mapping

Modalità di fetching: FetchMode.DEFAULT (configurazione del mapping file) FetchMode.JOIN (Hibernate recupera i dati associati, anche

collezioni, utilizzando un join all’interno della stessa select) FetchMode.SELECT (Hibernate effettua una seconda select

separata per recuperare le entity o collection associate) N.B. Il caricamento pigro (lazy fetching) è il default per SELECT: la

seconda select viene eseguita solo quando l’applicazione accede veramente ai dati associati DAO, ORM e Hibernate

Page 92: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

92

Hibernate: Strategie di caching

Utilizzato per motivi di performance Idea di base: Rendere l’accesso al DB necessario solo quando si

devono reperire dati non sono già disponibili sulla cache

La applicazione può avere bisogno di svuotare (invalidare) la cache se il DB viene aggiornato o se non è possibile sapere se la cache mantiene ancora copie aggiornate

First-level cache Associata con l’oggetto Session

Second-level cache Associata con l’oggetto SessionFactory

DAO, ORM e Hibernate

Page 93: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

93

Hibernate: Strategie di caching

Cache di primo livello: usata da Hibernate all’interno dei confini di una singola transazione principalmente al fine di ridurre il numero di query SQL generate all’interno di una transazione Ad es. se un oggetto è modificato diverse volte

all’interno della medesima transazione, Hibernate genera un unico statement SQL UPDATE alla fine della transazione, con tutte le modifiche

Cache di secondo livello: mantiene dati al livello di Session Factory, utilizzabili da diverse transazioni (across transaction boundaries) Oggetti persistenti disponibili per l’intera

applicazione, non solo per l’utente che sta eseguendo le query e per il SessionBean associato

DAO, ORM e Hibernate

Page 94: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

94

Hibernate in azione

DAO, ORM e Hibernate

Cinque ingredienti principali di una applicazione che fa uso di Hibernate per la gestione della persistenza: le classi di dominio realizzate in Java una base di dati (per noi realizzata in DB2) un file XML che definisce il mapping di ogni classe

persistente uno o più file di configurazione di Hibernate le interfacce Hibernate per l'accesso alla base di

dati: Session, Transaction e Query + package org.hibernate

Page 95: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

95

Classi di dominio e DB

DAO, ORM e Hibernate

Sappiamo già come realizzarli dalle slide precedenti Esempio: classe “User” e relativa tabella “UTENTE”:

public class User { private String nome; private String cognome; private String username; private String password; private String email; private Indirizzo indirizzo; public User(){} public User(String user){ username=user; } … }

CREATE TABLE UTENTE( username VARCHAR(10) PRIMARY KEY, nome VARCHAR(15), cognome VARCHAR(15), cod_fis VARCHAR(16) UNIQUE, password VARCHAR(8), email VARCHAR(20), via VARCHAR(20), civico INT, cap VARCHAR(5), citta VARCHAR(15));

Page 96: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

96

File di mapping per le classi persistenti

DAO, ORM e Hibernate

File XML che definisce come si mappano le proprietà delle classi Java persistenti sulle tabelle del DB

Deve soddisfare la grammatica specificata all'interno di un apposito DTD chiamato hibernate-mapping-3.0.dtd

N.B. Per verificare la correttezza sintattica del file

XML, Hibernate cercherà il DTD all'interno del classpath e lo troverà nella libreria .jar di Hibernate (ammesso che il classpath la includa) qualora non dovesse trovare il DTD, Hibernate lo

cercherà all'indirizzo specificato nella dichiarazione del DOCTYPE

Page 97: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

97

File di mapping per le classi persistenti: Esempio

DAO, ORM e Hibernate

File User.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> <class name="User" table="UTENTE"> <id name="username" column="username"></id> <property name="nome" column=“nome"></property> <property name="cognome" column=“cognome"></property> <property name="email"></property> <property name="password"></property> </class> </hibernate-mapping>

Page 98: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

98

File di mapping per le classi persistenti: Commenti

DAO, ORM e Hibernate

L'elemento class dichiara il nome della classe persistente e la tabella a cui essa corrisponde dice a Hibernate come rendere persistente e

caricare gli oggetti della classe User sfruttando la tabella UTENTE, ovvero ogni istanza è rappresentata da una tupla della tabella

L'elemento id dichiara:

il nome della proprietà della classe che gioca il ruolo di identificatore Importante: una classe persistente è sempre

caratterizzata da una proprietà che ne identifica le istanze; una volta creato un oggetto della classe, tale proprietà non potrà essere modificata dalla applicazione • il corrispondente metodo set può essere definito privato

Page 99: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

99

File di mapping per le classi persistenti: Commenti

DAO, ORM e Hibernate

il nome dell'attributo della tabella che identifica le tuple mappate su oggetti (primary key)

L'elemento property dichiara il nome delle proprietà persistenti della classe e a quali attributi della tabella corrispondono; di default, nessuna proprietà è persistente Importante: come per la proprietà che identifica gli

oggetti, il nome della proprietà indica ad Hibernate quali metodi set e get usare

Page 100: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

100

File di configurazione per Hibernate

DAO, ORM e Hibernate

Hibernate costituisce la parte dell'applicazione che gestisce la persistenza, ovvero che si connette al DB ha bisogno di avere le informazioni necessarie per

effettuare la connessione, quali il DBMS, il driver JDBC, la base di dati, utente/password, etc.

Un file XML fornisce tutte queste informazioni Tale file deve soddisfare la grammatica specificata

nel DTD hibernate-configuration-3.0.dtd

Page 101: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

101

File di configurazione per Hibernate: Esempio

DAO, ORM e Hibernate

File 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> <!-- Database connection settings --> <property name="hibernate.connection.driver_class"> com.ibm.db2.jcc.DB2Driver</property> <property name="hibernate.connection.url"> jdbc:db2://diva:deis.unibo.it:50000/tw_stud</property> <property name="connection.username">*****</property> <property name="connection.password">*****</property>

Page 102: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

102

File di configurazione per Hibernate: Esempio

DAO, ORM e Hibernate

<!-- SQL dialect --> <property name="dialect"> org.hibernate.dialect.DB2Dialect</property> <!-- JDBC connection pool (use C3P0) --> <property name="c3p0.min_size">5</property> <property name="c3p0.max_size">20</property> <property name="c3p0.timeout">300</property> <property name="c3p0.max_statement">50</property> <!-- Show and print nice SQL on stdout --> <property name="show_sql">true</property> <property name="format_sql">true</property> <!-- List of XML mapping files --> <mapping resource="User.hbm.xml" /> </session-factory> </hibernate-configuration>

Page 103: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

103

File di configurazione per Hibernate: Commenti

DAO, ORM e Hibernate

L'elemento session-factory definisce le impostazioni per l'accesso a un particolare DB

Le proprietà il cui nome hanno la forma (hibernate).connection.* contengono le informazioni necessarie per impostare la connessione JDBC

La proprietà dialect specifica la variante di SQL che deve generare Hibernate

Page 104: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

104

File di configurazione per Hibernate: Commenti

DAO, ORM e Hibernate

Le proprieta c3p0.* indicano le impostazioni necessarie a configurare il software c3p0 per il pooling di connessioni min size: numero minimo di connessioni che

devono essere pronte in ogni momento max size: numero massimo di connessioni aperte

gestite dal pool timeout: tempo al termine del quale una

connessione aperta non più usata viene rimossa max statements: numero di prepared statements che sono mantenuti in cache

Infine mapping include l’elenco dei file di mapping XML

Page 105: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

105

Le interfacce Hibernate

DAO, ORM e Hibernate

Tre sono le interfacce principali per l'accesso al DB, tutte appartenenti al package org.hibernate

Session: ogni istanza rappresenta una sessione di comunicazione tra applicazione e base di dati comprende i metodi per salvare/caricare oggetti

nella/dalla base di dati Transaction: ogni istanza rappresenta una

transazione maggiore disaccoppiamento dell'applicazione: non

è necessario usare l'API JDBC per impostare una transazione

Page 106: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

106

Le interfacce Hibernate

DAO, ORM e Hibernate

Gioca il ruolo di gestore di transazioni in un sistema che accede a più DB all'interno di una unica unità di lavoro di sistema

Query: interfaccia che permette di creare ed eseguire query sia nel linguaggio di query di Hibernate (HQL) che in

SQL che usino al loro interno delle variabili

(:nomeVaraibile)

Page 107: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

107

Interfacce Hibernate: Esempio d'uso

DAO, ORM e Hibernate

File Bid.java package bid; import java.util.*; import org.hibernate.*; import persistence.HibernateUtil; public class Bid { public static void main(String[] args) { //First unit of work Session session = HibernateUtil.getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); User user = new User("pippo"); String userId = (String) session.save(user); tx.commit(); session.close();

Page 108: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

108

Interfacce Hibernate: Esempio d'uso

DAO, ORM e Hibernate

//Second unit of work session = HibernateUtil.getSessionFactory().openSession(); tx = session.beginTransaction(); user = (User) session.get(User.class,userId); user.setNome("Filippo"); tx.commit(); session.close(); //Third unit of work session = HibernateUtil.getSessionFactory().openSession(); tx = session.beginTransaction() List users = session.createSQLQuery("select * from UTENTE order by username").addEntity(User.class).list(); System.out.println(users.size()+" user(s) found: "); for (Iterator iter= users.iterator(); iter.hasNext(); ) { User userId = (User) iter.next(); System.out.println (userId.getNome()); } tx.commit(); session.close();

HibernateUtil.shutdown(); //Shutting down the application } }

Page 109: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

109

Interfacce Hibernate: Commenti

DAO, ORM e Hibernate

L'utilizzo della interfaccia Transaction imposta l'autocommit a false necessità di chiamare il metodo commit

Tutti i comandi SQL sono generati a runtime La prima unità di lavoro, quando eseguita,

corrisponde ad effettuare sul DB un comando SQL simile a:

insert into UTENTE (USERNAME,NOME,COGNOME, COD_FIS,PASSWORD,EMAIL,VIA,CIVICO,CAP,CITTA) values (’pippo’, null, null, null, null, null, null,

null, null, null);

Page 110: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

110

Interfacce Hibernate: Commenti

DAO, ORM e Hibernate

La seconda unità di lavoro mostra l'abilita di: caricare un oggetto dalla base di dati, a partire

dalla classe di cui è istanza e dal suo identificatore il metodo get(Class,Serializable) restituisce

una istanza della classe persistente data in input caratterizzata dall'identificatore in input, e null se la suddetta istanza non esiste

effettuare un dirty checking automatico: senza che sia richiesto esplicitamente di fare l'update dell'istanza, Hibernate si accorge delle modiche apportate sulla proprietà nome ed aggiorna automaticamente la base di dati

Page 111: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

111

Interfacce Hibernate: Commenti

DAO, ORM e Hibernate

La terza unita di lavoro mostra come è possibile incapsulare una query di accesso al DB e ricavare dai risultati oggetti del dominio questo tipo di accesso deve essere limitato a quei

casi in cui è necessario effettuare una ricerca sul DB non di tipo diretto, ad esempio, FindByCriteria

Page 112: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

112

Inizializzazione di Hibernate: SessionFactory

DAO, ORM e Hibernate

Per inizializzare Hibernate, si costruisce un oggetto SessionFactory a partire da un oggetto Configuration

Un oggetto Configuration, sostanzialmente, rappresenta il file di configurazione di Hibernate SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

quando new Configuration()è invocato, Hibernate cerca un file chiamato hibernate.properties e tutte le impostazioni definite sono associate all'oggetto di Configuration

quando configure()è invocato, Hibernate cerca il file hibernate.cfg.xml

Page 113: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

113

Inizializzazione di Hibernate: SessionFactory

DAO, ORM e Hibernate

Nella maggior parte delle applicazioni, SessionFactory deve essere istanziato una sola volta durante la fase di inizializzazione di Hibernate, e gioca il ruolo di gestore delle sessioni, nel senso che ogni istanza di Session deve essere creata a partire da lui è buona prassi realizzare una classe HibernateUtil

per l'inizializzazione di Hibernate e la gestione della singola istanza di SessionFactory

Page 114: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

114

Gestore delle sessioni: HibernateUtil

DAO, ORM e Hibernate

File HibernateUtil.java package persistence; import org.hibernate.*; import org.hibernate.cfg.*; public class HibernateUtil { private static SessionFactory sessionFactory = initHibernateUtil(); private static SessionFactory initHibernateUtil(){ try { return new Configuration().configure().buildSessionFactory(); } catch (HibernateException ex) { throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void shutdown() { getSessionFactory().close(); //Close caches and connection pools } }

Page 115: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

115

Mappare una classe Java significa...

DAO, ORM e Hibernate

Stabilire una corrispondenza tra le sue istanze e le tuple della tabella corrispondente

Mappare il suo identificatore Mappare le sue proprietà persistenti proprietà che sono valori proprietà che sono istanze di una altra classe di

dominio Java

Page 116: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

116

Mappare gli identificatori delle classi di dominio

DAO, ORM e Hibernate

Dal punto di vista sintattico, una proprietà che identifica una classe deve essere mappata attraverso l'elemento XML <id> (che deve essere definito)

<id> può avere un elemento figlio <generator> che deve avere un attributo class che specifica una classe Java che implementa l'interfaccia

org.hibernate.id.IdentifierGenerator e che viene usata per generare identificatori unici ; Hibernate viene fornito con delle classi built-in per generare identificatori, tra le altre: assigned: significa che l'applicazione assegna

l'identificatore all'istanza prima che sia chiamato il metodo save - questo è il comportamento di default se generator non compare

native: usa i generatori di identificatori forniti dal DBMS sottostante; mantiene il mapping portabile

Page 117: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

117

Mappare proprietà delle classi di dominio

DAO, ORM e Hibernate

Abbiamo già visto come mappare una proprietà persistente di una classe quando la stessa corrisponde a un valore con molteplicità massima pari a uno mediante l’uso dell'elemento XML property

Quando invece una proprietà è una collezione omogenea di valori gestiti da una altra tabella , allora nel file di mapping si definisce un elemento apposito, quale Set, List, ecc.

Si rimanda alla documentazione e al materiale dell’esercitazione guidata in laboratorio per dettagli

Diciamo qualcosa in più sul sistema di tipi di Hibernate…

Page 118: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

118

Il sistema di tipi di Hibernate

DAO, ORM e Hibernate

I tipi Hibernate sono di fatto dei convertitori che traducono da tipi Java a tipi SQL e viceversa

La maggior parte dei tipi built-in di Hibernate hanno lo stesso nome del tipo Java che mappano

Possono però esserci più tipi Hibernate per uno stesso tipo Java bisogna allora indicare nel file di mapping il tipo di

mapping che Hibernate deve usare

Page 119: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

119

Tipi primitivi di Hibernate: Corrispondenze SQL-Java

DAO, ORM e Hibernate

Page 120: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

120

Tipi di dati Hibernate sulle date e il tempo

DAO, ORM e Hibernate

Page 121: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

121

Come usare i tipi di Hibernate nei mapping: Esempio

DAO, ORM e Hibernate

<class name="Item" table="ITEM"> (...) <property name="giornoInizio" type="time"

column="INIZIO"/> </class>

N.B. Se non specifichiamo il tipo di Hibernate, allora Hibernate usa la reflection, ovvero risale al tipo Java della proprietà giornoInizio della classe Item e assume un comportamento di default se abbiamo definito la proprietà giornoInizio di

tipo java.util.Date, Hibernate cerca di convertirla nel tipo TIMESTAMP (diverso da TIME)

Page 122: Tecnologie Web T Metodologie di Progettazione …...5 Conflitto di impedenza (3/4) In generale, i dati risiedono nel database (DB) mentre la logica applicativa viene implementata da

122

Riferimenti DAO:

http://java.sun.com/blueprints/corej2eepatterns/ Patterns/DataAccessObject.html

ORM: http://www.agiledata.org/essays/mappingObjects.html

Hibernate: http://www.hibernate.org/ http://www.visualbuilder.com/java/hibernate/ tutorial/

http://docs.jboss.org/hibernate/stable/core/ reference/en/html/

API: http://docs.jboss.org/hibernate/core/3.5/api/

Helen Feddema. “DAO Object Model: The Definitive Reference”,

O'Reilly Media Christian Bauer and Gavin King. “Java Persistence with

Hibernate”, Manning DAO, ORM e Hibernate