JPA Java Persistence API. Nello sviluppo web con Java, si lavora sempre con database come SQL Server, MySQL, Oracle, … Quindi, ci sono molte modalità di implementazione con il database tramite l’utilizzo di ORM (Object Relational Mapping) come Hibernate, EclipseLink, TopLink, Spring Data JPA.
Pertanto, la comprensione dell’architettura di JPA è utile per gli sviluppatori. In questo articolo parleremo dell’architettura di JPA. In particolare tratteremo:
- Problematiche ricorrenti
- Soluzione di JPA
- L’architettura di JPA
- Vantaggi e svantaggi
- Conclusioni
Problematiche ricorrenti
Prima della nascita di JPA, si utilizzava JDBC per lavorare con i database. Utilizza il pattern facade per astrarre tutti i tipi di database. In questo modo gli sviluppatori possono occuparsi solo delle tabelle dei database, senza le loro differenze.
Ma JDBC ha ancora alcuni svantaggi che dobbiamo conoscere.
Si mappa un membro dei dati su una colonna della tabella. Questo non è centrato sull’oggetto.
In JDBC non è disponibile alcuna mappatura predefinita con le tabelle.
JDBC funziona utilizzando le basi di SQL. Quindi è possibile utilizzare alcune funzionalità speciali di ciascun RDBMS.
JDBC utilizza codice specifico per il database.
Non è disponibile il versioning o il timestamping automatico.
Soluzione di JPA
Per risolvere tutti gli inconvenienti di JDBC, si ricorre alla tecnica ORM (Object Relational Mapping). JPA, iBatis, … sono alcune tecniche ORM che uno sviluppatore deve conoscere.
JPA Java Persistence API è lo standard Java per la mappatura degli oggetti Java su un database relazionale. La mappatura degli oggetti Java alle tabelle del database e viceversa è chiamata Object-relational mapping (ORM). La JPA Java Persistence API è un possibile approccio all’ORM. Tramite JPA, lo sviluppatore può mappare, memorizzare, aggiornare e recuperare dati da database relazionali a oggetti Java e viceversa. JPA può essere utilizzato in applicazioni Java-EE e Java-SE.
JPA definisce solo le specifiche, non fornisce un’implementazione.
L’implementazione di JPA è fornita come implementazione di riferimento dai fornitori che sviluppano O/R Mapper come Hibernate, EclipseLink e Apache OpenJPA.
JPA permette allo sviluppatore di lavorare direttamente con gli oggetti piuttosto che con le istruzioni SQL. L’implementazione JPA è tipicamente chiamata provider di persistenza.
Providers JPA
JPA è un’API open source, pertanto diversi fornitori aziendali come Oracle, Redhat, Eclipse, ecc. forniscono nuovi prodotti aggiungendo il sapore della persistenza JPA.
Alcuni di questi prodotti includono:
- Hibernate
- EclipseLink
- TopLink
- Spring Data JPA
- altri…
L’architettura di JPA
In questo articolo ci concentreremo sui componenti di JPA.
PersistenceProvider
In base alle informazioni sul database, come url, nome utente, password, …, crea un’istanza di EntityManagerFactory.
In JPA, si tratta di un’interfaccia. Gli altri fornitori devono implementare questa interfaccia.
EntityManagerFactory
È una classe di factory di EntityManager. Viene utilizzata per creare istanze multiple della classe EntityManager.
Se è necessario accedere a più database, è necessario configurare una EntityManagerFactory per ogni database.
EntityManager
EntityManager gestisce le entità dell’applicazione. Fornisce alcune operazioni per interagire con il database attraverso il driver del database, come le operazioni CRUD, …
EntityManager può utilizzare più istanze di Query.
EntityManager ed EntityTransaction hanno una relazione uno-a-uno.
EntityTransaction
Questa classe fornisce alcune operazioni che soddisfano le proprietà ACID degli RDBMS.
Query
Questa interfaccia è implementata da ogni fornitore JPA per trovare gli oggetti di persistenza che soddisfano determinati criteri.
Entity
Un’entità è un oggetto di dominio persistente. Ogni classe di entità rappresenterà una tabella del nostro database e l’istanza di un’entità conterrà i dati di una singola riga di quella tabella.
Ogni entità avrà un campo id che rappresenta la chiave primaria della tabella.
Persistence Unit
Un’unità di persistenza specifica tutte le tabelle di entità, che sono gestite dagli EntityManager dell’applicazione. Ogni unità di persistenza contiene tutte le classi che rappresentano i dati memorizzati in un singolo database.
Alcune eccezioni in JPA
In JPA, tutte le eccezioni specifiche sono sottoclassi della classe PersistenceException.
- TransactionRequiredException: Viene lanciata dal fornitore di persistenza quando una transazione è richiesta ma non è attiva.
- RollbackException: Viene lanciata dal fornitore di persistenza quando EntityTransaction.commit() fallisce.
- EntityExistsException: Viene lanciata dal fornitore di persistenza quando viene richiamato EntityManager.persist(Object) e l’entità esiste già. La transazione corrente, se è attiva, sarà contrassegnata per il rollback.
- LockTimeoutException: Viene lanciata dal fornitore di persistenza quando si verifica un conflitto di lock pessimistico che non porta al rollback della transazione.Questa eccezione può essere lanciata come parte di una chiamata API, al momento del flush o del commit. La transazione corrente, se è attiva, non sarà contrassegnata per il rollback.
- OptimisticLockException: Viene lanciata dal fornitore di persistenza quando si verifica un conflitto di locking ottimistico. Questa eccezione può essere lanciata come parte di una chiamata API, di un flush o al momento del commit. La transazione corrente, se è attiva, sarà contrassegnata per il rollback.
- PessimisticLockException: Viene lanciata dal fornitore di persistenza quando si verifica un conflitto di locking pessimistico. Questa eccezione può essere lanciata come parte di una chiamata API, di un flush o al momento del commit. La transazione corrente, se è attiva, sarà contrassegnata per il rollback.
- EntityNotFoundException: Viene lanciata dal fornitore di persistenza quando si accede a un riferimento di entità ottenuto da EntityManager.getReference, ma l’entità non esiste. Viene lanciata quando viene richiamato EntityManager.refresh e l’oggetto non esiste più nel database. Viene Lanciato quando viene utilizzato EntityManager.lock con blocco pessimistico e l’entità non esiste più nel database.
- NonUniqueResultException: Viene lanciata dal fornitore di persistenza quando Query.getSingleResult() o TypedQuery.getSingleResult() viene eseguito su una query e c’è più di un risultato dalla query. Questa eccezione non causa la marcatura della transazione corrente, se è attiva, per il rollback.
- NoResultException: Viene lanciata dal fornitore di persistenza quando Query.getSingleResult() o TypedQuery.getSingleResult()viene eseguita su una query e non c’è alcun risultato da restituire. Questa eccezione non causa la marcatura della transazione corrente, se è attiva, per il rollback.
- QueryTimeoutException: Viene lanciata dal fornitore di persistenza quando una query va in timeout e viene eseguito il rollback solo dell’istruzione. La transazione corrente, se è attiva, non sarà contrassegnata per il rollback.
Vantaggi e svantaggi:
- Mappa un oggetto alla tabella.
- Supporta il proprio linguaggio di query invece di SQL.
- Codice meno dipendente dal database.
- Codice a bassa manutenzione.
- Ottimizza le prestazioni grazie alla cache.
- Fornisce modalità per il versioning automatico e il timestamping.
- Astrae tutte le operazioni che interagiscono con i database. In questo modo possiamo passare ad altri database senza preoccupazioni.
Conclusioni
In Hibernate, l’interfaccia Session segue il modello Repository. Tuttavia, introducendo le nostre interfacce di repository, disaccoppiamo i nostri oggetti di dominio dall’implementazione di Hibernate, rendendo il pacchetto del modello di dominio facile da testare e riutilizzare.
(fonte)
Innovaformazione, scuola informatica specialistica promuove la sviluppo in Java per il web ed i framework Java come Spring. Corsi attivati per aziende.
INFO: info@innovaformazione.net / Tel. 3471012275 (Dario Carrassi)