Domanda

Esiste una valida alternativa a Hibernate? Preferibilmente qualcosa che non si basa su JPA.

Il nostro problema è che stiamo costruendo un sistema RIA con stato complesso (come in molti oggetti si riferiscono l'un l'altro). Sembra che Hibernate sia progettato per essere utilizzato principalmente su applicazioni una tantum: JSF e simili.

Il problema è principalmente quello del caricamento lento. Dal momento che possono esserci diverse richieste HTTP tra l'inizializzazione e il caricamento effettivo di raccolte pigre, una sessione per transazione è fuori questione. Anche una sessione di lunga durata (una per applicazione) non funziona bene, perché una volta che una transazione colpisce un intoppo e genera un'eccezione, l'intera sessione viene invalidata, quindi gli oggetti caricati in modo pigro si rompono. Quindi ci sono tutti i tipi di cose che semplicemente non funzionano per noi (come il persistere di dati impliciti di dati esterni a una transazione inizializzata).

Le mie povere spiegazioni a parte, la linea di fondo è che Hibernate fa magie che non ci piacciono. Sembra che TopLink non sia migliore, ma è anche scritto su EJB.

Quindi, un livello di persistenza senza stato (o persino un livello di astrazione del database orientato agli oggetti abbastanza luminoso) è ciò di cui avremmo maggiormente bisogno.

Qualche idea o sto chiedendo qualcosa che non esiste?

Modifica: mi dispiace per la mia ambigua terminologia e ringrazio tutti per le correzioni e le risposte perspicaci. Coloro che mi hanno corretto, avete tutti ragione, intendevo JPA, non EJB.

È stato utile?

Soluzione

Come accennato, JPA < > EJB, non sono nemmeno correlati. EJB 3 sembra sfruttare l'APP, ma questo è tutto. Abbiamo un sacco di cose che usano JPA che non si avvicinano nemmeno all'esecuzione di EJB.

Il tuo problema non è la tecnologia, è il tuo design.

O, dovrei dire, il tuo design non si adatta facilmente a QUALSIASI framework moderno.

In particolare, stai cercando di mantenere attive le transazioni su diverse richieste HTTP.

Naturalmente, la maggior parte di ogni linguaggio comune è che ogni richiesta è di per sé una o più transazioni, piuttosto che ogni richiesta è una parte di una transazione più ampia.

C'è anche un'evidente confusione quando hai usato il termine " stateless " e " transazione " nella stessa discussione, poiché le transazioni sono intrinsecamente stateful.

Il tuo grosso problema è semplicemente la gestione manuale delle tue transazioni.

Se la tua transazione si sta verificando su più richieste HTTP, E quelle richieste HTTP sono in esecuzione " molto velocemente " ;, subito l'una dopo l'altra, non dovresti davvero avere alcun problema reale , ad eccezione del fatto che dovrai assicurarti che le tue richieste HTTP utilizzino la stessa connessione DB per sfruttare la funzione di transazione dei database.

Cioè, in termini semplici, ottieni una connessione al DB, inseriscilo nella sessione e assicurati che per tutta la durata della transazione, tutte le tue richieste HTTP passino non solo per quella stessa sessione, ma in in modo tale che la connessione effettiva sia ancora valida. In particolare, non credo che esista una connessione JDBC standardizzata che sopravviverà effettivamente al failover o al bilanciamento del carico da una macchina all'altra.

Quindi, semplicemente, se si desidera utilizzare le transazioni DB, è necessario assicurarsi di utilizzare la stessa connessione DB.

Ora, se la tua transazione a lungo termine ha " interazioni utente " al suo interno, ovvero si avvia la transazione DB e si attende che l'utente " faccia qualcosa " quindi, semplicemente, quel design è tutto sbagliato. NON vuoi farlo, poiché le transazioni di lunga durata, specialmente in ambienti interattivi, sono semplicemente cattive. Come & Quot; Crossing The Streams & Quot; Male. Non farlo Le transazioni batch sono diverse, ma le transazioni interattive di lunga durata sono Bad.

Desideri mantenere le tue transazioni interattive di breve durata quanto pratiche.

Ora, se NON puoi assicurarti di essere in grado di utilizzare la stessa connessione DB per la tua transazione, quindi, congratulazioni, puoi implementare le tue transazioni. Ciò significa che puoi progettare il tuo sistema e i flussi di dati come se non avessi alcuna capacità transazionale sul back-end.

Ciò significa essenzialmente che dovrai inventare il tuo meccanismo per " commit " i tuoi dati.

Un buon modo per farlo sarebbe quello di costruire i tuoi dati in modo incrementale in una singola " transazione " documento, quindi inviare quel documento a un " save " routine che fa gran parte del vero lavoro. Ad esempio, è possibile memorizzare una riga nel database e contrassegnarla come & Quot; unsaved & Quot ;. Lo fai con tutte le tue righe e infine chiami una routine che attraversa tutti i dati che hai appena archiviato e li contrassegna come & Quot; save & Quot; in un processo mini-batch a transazione singola.

Nel frattempo, tutti gli altri SQL " ignorano " dati che non sono " salvati " ;. Lancia alcuni timestamp e fai scavare il processo di un mietitore (se vuoi davvero preoccuparti - potrebbe essere più economico lasciare semplicemente righe morte nel DB, dipende dal volume), queste & Quot; unsaved quot; righe, poiché sono " non impegnate " transazioni.

Non è così male come sembra. Se vuoi davvero un ambiente senza stato, che è quello che mi sembra, allora dovrai fare qualcosa del genere.

Mente, in tutto ciò la tecnologia della persistenza non ha davvero nulla a che fare con it. Il problema è come usi le tue transazioni, piuttosto che la tecnologia così tanto.

Altri suggerimenti

Se stai cercando un altro provider JPA (Hibernate è uno di questi), dai un'occhiata a EclipseLink . È molto più completo rispetto all'implementazione di riferimento JPA 1.0 di TopLink Essentials. In effetti, EclipseLink sarà l'implementazione di riferimento di JPA 2.0 fornita con Glassfish V3 Final.

JPA è buono perché puoi usarlo sia all'interno che all'esterno di un contenitore. Ho scritto client Swing che usano JPA con buoni risultati. Non ha lo stesso stigma e il bagaglio XML forniti con EJB 2.0 / 2.1.

Se stai cercando una soluzione ancora più leggera, non cercare oltre ibatis , che considero essere la mia tecnologia di persistenza preferita per la piattaforma Java. È leggero, si basa su SQL (è incredibile quanto tempo gli utenti ORM impiegano nel tentativo di far produrre loro un buon SQL) e fa il 90-95% di ciò che fa JPA (incluso il caricamento lazy di entità correlate se lo desideri).

Solo per correggere un paio di punti:

  • JPA è il livello di peristenza di EJB, non costruito su EJB;
  • Qualsiasi provider JPA decente ha un sacco di cache in corso e può essere difficile capire tutto (questo sarebbe un buon esempio di " Perché Simplicity So Complex? ") . A meno che tu non stia facendo qualcosa che non hai indicato, le eccezioni non dovrebbero essere un problema per i tuoi oggetti gestiti. Eccezioni di runtime in genere transazioni di rollback (se si utilizza la gestione delle transazioni di Spring e chi non lo fa?). Il provider gestirà copie memorizzate nella cache degli oggetti caricati o persistenti. Questo può essere problematico se si desidera aggiornare al di fuori del gestore entità (che richiede un flush esplicito della cache o l'utilizzo di EntityManager.refresh()).

Penso che dovresti dare un'occhiata a apache cayenne che è un'ottima alternativa a " & grande quot; quadri. Con il suo modellatore decente, la curva di apprendimento è ridotta da una buona documentazione.

Ho guardato SimpleORM lo scorso anno e sono rimasto molto colpito dal suo design leggero e non magico . Ora sembra esserci una versione 3, ma non ho alcuna esperienza con quella.

Ebean ORM ( http://www.avaje.org )

È un ORM più semplice e intuitivo da usare.

  • Utilizza le annotazioni JPA per la mappatura (@Entity, @OneToMany ecc.)
  • API Sessionless - Nessuna sessione di ibernazione o Gestione entità JPA
  • Il caricamento lento funziona e basta
  • Supporto parziale degli oggetti per prestazioni migliori
  • Sintonia automatica delle query tramite " Recupero automatico "
  • Integrazione primaverile
  • Supporto per query di grandi dimensioni
  • Ottimo supporto per l'elaborazione batch
  • Recupero sfondo
  • Generazione DDL
  • Puoi usare SQL raw se vuoi (buono come Ibatis)
  • Licenza LGPL

  • Rob.

BEA Kodo (precedentemente Solarmetric Kodo) è un'altra alternativa. Supporta JPA, JDO ed EJ3. È altamente configurabile e può supportare il prelievo aggressivo, il distacco / il collegamento di oggetti, ecc.

Tuttavia, da quanto descritto, Toplink dovrebbe essere in grado di gestire i tuoi problemi. Principalmente, sembra che tu debba essere in grado di collegare / staccare oggetti dal livello di persistenza quando le richieste iniziano e finiscono.

Solo per riferimento, perché il design del PO è il suo problema più grande: la suddivisione delle transazioni tra richieste di più utenti significa che puoi avere tante transazioni aperte in un determinato momento quanti sono gli utenti connessi alla tua app - una transazione mantiene occupata la connessione fino al viene eseguito il commit / rollback. Con migliaia di utenti connessi contemporaneamente, ciò può potenzialmente significare migliaia di connessioni. La maggior parte dei database non supporta questo.

Né Hibernate né Toplink (EclipseLink) sono basati su EJB, sono entrambi framework di persistenza POJO (ORM).

Sono d'accordo con la risposta precedente: iBatis è una buona alternativa ai framework ORM: pieno controllo su sql, con un buon meccanismo di memorizzazione nella cache.

Un'altra opzione è Torque, non sto dicendo che sia migliore di una qualsiasi delle opzioni sopra menzionate, ma solo che è un'altra opzione da guardare. Ora sta diventando piuttosto vecchio ma potrebbe soddisfare alcune delle tue esigenze.

Torque

Quando stavo cercando un sostituto di Hibernate, mi sono imbattuto in DataNucleus Access Platform , che è un ORM con licenza Apache2. Non è solo ORM in quanto fornisce persistenza e recupero di dati anche in altre origini dati diverse da RDBMS, come LDAP, DB4O e XML. Non ho alcuna esperienza di utilizzo, ma sembra interessante.

Valuta di rompere completamente il tuo paradigma con qualcosa come tox . Se hai bisogno di classi Java, puoi caricare il risultato XML in JDOM .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top