Parlando come qualcuno che ha trascorso un bel po 'di tempo a lavorare con JPA (Java Persistence API, fondamentalmente l'API ORM standardizzata per Java / J2EE / EJB), che include Hibernate, EclipseLink, Toplink, OpenJPA e altri, condividerò alcuni dei miei osservazioni.
- Gli ORM non sono veloci. Possono essere adeguati e il più delle volte adeguati sono OK, ma in un ambiente ad alto volume a bassa latenza sono un no-no;
- In linguaggi di programmazione generici come Java e C # hai bisogno di un sacco di magia per farli funzionare (ad es. Tessitura a tempo di caricamento in Java, strumentazione, ecc.);
- Quando si utilizza un ORM, piuttosto che allontanarsi da SQL (che sembra essere l'intento), rimarrete stupiti da quanto tempo impiegate a modificare XML e / o annotazioni / attributi per far sì che il vostro ORM generi SQL performante;
- Per query complesse, non c'è davvero alcun sostituto. Come in JPA ci sono alcune query che semplicemente non sono possibili che sono in SQL raw e quando devi usare SQL grezzo in JPA non è carino (C # /. Net almeno ha tipi dinamici - var - che è molto più bello di un array di oggetti);
- Ci sono moltissimi "gotchas" quando si usano gli ORM. Ciò include un comportamento involontario o imprevisto, il fatto che è necessario integrare la capacità di eseguire aggiornamenti SQL sul database (utilizzando refresh () in JPA o metodi simili perché JPA per impostazione predefinita memorizza nella cache tutto in modo da non catturare un database diretto aggiornamento - l'esecuzione di aggiornamenti SQL diretti è un'attività di supporto alla produzione comune);
- La mancata corrispondenza relazionale agli oggetti causerà sempre problemi. Con tale problema c'è un compromesso tra complessità e completezza dell'astrazione. A volte ho sentito che l'APP è andato troppo oltre e ha colpito una vera legge di rendimenti decrescenti in cui il colpo di complessità non era giustificato dall'astrazione.
C'è un altro problema che richiede un po 'più di spiegazione.
Il modello tradizionale per un'applicazione Web è avere un livello di persistenza e un livello di presentazione (possibilmente con un servizio o altri livelli nel mezzo ma questi sono i due importanti per questa discussione). Gli ORM impongono una vista rigida dal livello di persistenza fino al livello di presentazione (ovvero le entità).
Una delle critiche a metodi SQL più grezzi è che si finisce con tutti questi VO (oggetti valore) o DTO (oggetti trasferimento dati) che vengono utilizzati da una sola query. Questo è pubblicizzato come un vantaggio degli ORM perché te ne sbarazzi.
La cosa è che questi problemi non vanno via con gli ORM, ma semplicemente passano al livello di presentazione. Invece di creare VO / DTO per le query, si creano oggetti di presentazione personalizzati, in genere uno per ogni vista. Come va meglio? IMHO non lo è.
Ne ho scritto in ORM o SQL: ci siamo ancora? .
La mia tecnologia di persistenza di scelta (in Java) in questi giorni è ibatis. È un wrapper piuttosto sottile attorno a SQL che fa il 90% + di ciò che JPA può fare (può persino fare un caricamento lento delle relazioni sebbene non sia ben documentato) ma con un sovraccarico molto meno (in termini di complessità e codice reale).
Questo è successo l'anno scorso in un'applicazione GWT che stavo scrivendo. Molta traduzione da EclipseLink a oggetti di presentazione nell'implementazione del servizio. Se stessimo usando ibatis sarebbe stato molto più semplice creare gli oggetti appropriati con ibatis e poi passarli su e giù per lo stack. Alcuni puristi potrebbero obiettare che si tratta di Bad ™. Forse è così (in teoria) ma ti dico una cosa: avrebbe portato a un codice più semplice, uno stack più semplice e una maggiore produttività.