2009-01-05 15 views
6

Gibt es eine echte Alternative zu Hibernate? Vorzugsweise etwas, das nicht auf JPA basiert.Eine Alternative zu Hibernate oder TopLink?

Unser Problem ist, dass wir ein komplexes (wie in, viele Objekte beziehen sich aufeinander) Stateful RIA System aufbauen. Es scheint, als wäre Hibernate hauptsächlich für einmalige Anwendungen - JSF und dergleichen - gedacht.

Das Problem besteht hauptsächlich in der Lazy Loading. Da zwischen der Initialisierung und dem tatsächlichen Laden von Lazy Collections mehrere HTTP-Requests liegen können, kommt eine Sitzung pro Transaktion nicht in Frage. Eine langlebige Sitzung (eine pro Anwendung) funktioniert auch nicht gut, denn sobald eine Transaktion einen Fehler feststellt und eine Ausnahme auslöst, wird die gesamte Sitzung ungültig, wodurch die Lazy-geladenen Objekte unterbrochen werden. Dann gibt es alle möglichen Dinge, die für uns einfach nicht funktionieren (wie implizite Daten, die von Daten außerhalb einer initialisierten Transaktion bestehen).

Meine schlechten Erklärungen beiseite, die Quintessenz ist, dass Hibernate Magie macht, die wir nicht mögen. Es scheint, dass TopLink nicht besser ist, es wird auch auf EJB geschrieben.

Also, eine zustandslose Persistenzschicht (oder sogar helle genug objektorientierte Datenbank Abstraktionsschicht) ist, was wir am meisten brauchen würden.

Irgendwelche Gedanken, oder frage ich nach etwas, das nicht existiert?

Bearbeiten: Es tut mir leid für meine mehrdeutige Terminologie, und danke Ihnen allen für Ihre Korrekturen und aufschlussreiche Antworten. Diejenigen, die mich korrigiert haben, Sie sind alle richtig, ich meinte JPA, nicht EJB.

+0

Muss Ihr Paradigma ein ORM sein? – dacracot

Antwort

6

Wie erwähnt, JPA <> EJB, sie sind nicht einmal verwandt. EJB 3 nutzt JPA, aber das ist es auch schon. Wir haben eine Menge Dinge, die JPA verwenden, die EJB nicht einmal nahe kommen.

Ihr Problem ist nicht die Technologie, es ist Ihr Design.

Oder sollte ich sagen, Ihr Design ist nicht einfach auf ziemlich jedem modernen Rahmen passen.

Insbesondere versuchen Sie, Transaktionen über mehrere HTTP-Anforderungen am Leben zu erhalten.

Natürlich ist jedes gängige Idiom, dass jede Anfrage in sich eine oder mehrere Transaktionen ist, anstatt jede Anfrage ein Teil einer größeren Transaktion zu sein.

Es gibt auch offensichtliche Verwirrung, wenn Sie den Begriff "staatenlos" und "Transaktion" in der gleichen Diskussion verwendet, da Transaktionen von Natur aus stateful sind.

Ihr großes Problem ist einfach Ihre Transaktionen manuell zu verwalten.

Wenn die Transaktion über mehrere HTTP-Anfragen läuft, und diese HTTP-Anfragen "sehr schnell" ausgeführt werden, dann sollten Sie nicht wirklich ein echtes Problem haben, speichern Sie, dass Sie müssen Stellen Sie sicher, dass Ihre HTTP-Anforderungen dieselbe Datenbankverbindung verwenden, um die Transaktionsfunktion Datenbanken zu nutzen.

Das heißt, in einfachen Worten, erhalten Sie eine Verbindung mit der DB, stopfen Sie es in der Sitzung, und stellen Sie sicher, dass für die Dauer der Transaktion alle Ihre HTTP-Anfragen nicht nur die gleiche Sitzung durchlaufen so dass die eigentliche Verbindung noch gültig ist. Insbesondere glaube ich nicht, dass es eine JDBC-Verbindung von der Stange gibt, die Failover oder Lastausgleich von einer Maschine zur anderen überlebt.

Also, einfach, wenn Sie DB-Transaktionen verwenden möchten, müssen Sie sicherstellen, dass Sie die gleiche DB-Verbindung verwenden.

Nun, wenn Ihre lang laufende Transaktion "Benutzerinteraktionen" innerhalb hat, d. H. Sie starten die DB-Transaktion und warten auf den Benutzer "etwas zu tun", dann ist dieses Design ganz einfach falsch. Das wollen Sie nicht tun, da Transaktionen mit langer Lebensdauer, besonders in interaktiven Umgebungen, einfach schlecht sind. Wie "Crossing The Streams" schlecht. Tu es nicht. Batch-Transaktionen sind unterschiedlich, aber interaktive langlebige Transaktionen sind schlecht.

Sie möchten Ihre interaktiven Transaktionen so kurz wie möglich halten.

Jetzt, wenn Sie nicht sicherstellen können, dass Sie die gleiche DB-Verbindung für Ihre Transaktion verwenden können, dann, herzlichen Glückwunsch, können Sie Ihre eigenen Transaktionen implementieren. Das bedeutet, dass Sie Ihre System- und Datenflüsse so gestalten müssen, als hätten Sie keine Transaktionsfunktionalität am Backend.

Das bedeutet im Wesentlichen, dass Sie mit Ihrem eigenen Mechanismus kommen müssen, um Ihre Daten zu "committen".

Ein guter Weg, dies zu tun wäre, wo Sie Ihre Daten schrittweise in einem einzigen "Transaktion" -Dokument aufbauen, dann füttern das Dokument zu einer "Speichern" -Routine, die viel von der eigentlichen Arbeit macht. Sie könnten beispielsweise eine Zeile in der Datenbank speichern und sie als "nicht gespeichert" kennzeichnen. Sie tun das mit all Ihren Zeilen und rufen schließlich eine Routine auf, die alle Daten durchläuft, die Sie gerade gespeichert haben, und markiert sie alle als "gespeichert" in einem einzelnen Transaktion Mini-Batch-Prozess.

In der Zwischenzeit "ignoriert" all Ihre anderen SQL-Daten Daten, die nicht "gespeichert" werden. Werfen Sie einige Zeitstempel ein und lassen Sie einen Reaper-Prozess auffliegen (wenn Sie wirklich Ärger machen wollen - es könnte tatsächlich billiger sein, tote Zeilen in der DB zu belassen, hängt vom Volumen ab), diese toten "ungespeicherten" Zeilen, wie diese sind "nicht genehmigte" Transaktionen.

Es ist nicht so schlimm wie es klingt. Wenn Sie wirklich eine zustandslose Umgebung wollen, so wie es sich für mich anhört, dann müssen Sie so etwas tun.

Bedenken Sie, in all dem hat die Persistenz Tech wirklich nichts damit zu tun. Das Problem ist, wie Sie Ihre Transaktionen verwenden, anstatt die Technologie so sehr.

+0

Danke für Ihre Kommentare. Sorry für die Unklarheit mit meiner Terminologie, aber Sie haben unser Problem in den Kopf getroffen. Genau das tut unser Team momentan. Ich hatte nur gehofft, dass es einen einfacheren Weg gegeben hätte ... –

7

Wenn Sie nach einem anderen JPA-Anbieter suchen (Hibernate ist einer davon), dann werfen Sie einen Blick auf EclipseLink. Es ist viel umfassender als die JPA 1.0-Referenzimplementierung von TopLink Essentials. In der Tat wird EclipseLink die JPA 2.0-Referenzimplementierung sein, die mit Glassfish V3 Final ausgeliefert wird.

JPA ist gut, weil Sie es sowohl innerhalb als auch außerhalb eines Containers verwenden können. Ich habe Swing-Clients geschrieben, die mit JPA arbeiten. Es hat nicht das gleiche Stigma und XML-Gepäck wie EJB 2.0/2.1.

Wenn Sie nach einer noch leichteren Lösung suchen, dann suchen Sie nicht weiter als ibatis, die ich für meine Persistenz-Technologie der Wahl für die Java-Plattform halte. Es ist leichtgewichtig, basiert auf SQL (es ist erstaunlich, wie viel Zeit ORM-Benutzer damit verbringen, ORM zu guter SQL zu machen) und macht 90-95% von dem, was JPA tut (einschließlich des verzögerten Ladens verwandter Entitäten, wenn Sie wollen).

einfach ein paar Punkte zu korrigieren:

  • JPA ist die peristence Schicht von EJB, nicht auf EJB gebaut;
  • Jeder anständige JPA-Anbieter hat eine Menge Caching und es kann schwer sein, alles herauszufinden (dies wäre ein gutes Beispiel für "Warum ist Simplicity So Complex?"). Wenn Sie nichts tun, was Sie nicht angegeben haben, sollten Ausnahmen für Ihre verwalteten Objekte kein Problem darstellen. Laufzeitausnahmen führen normalerweise Rollback-Transaktionen durch (wenn Sie die Transaktionsverwaltung von Spring verwenden und wer nicht?). Der Anbieter behält zwischengespeicherte Kopien geladener oder beibehaltener Objekte bei. Dies kann problematisch sein, wenn Sie außerhalb des Entitätsmanagers aktualisieren möchten (ein expliziter Cache-Flush oder die Verwendung von EntityManager.refresh() erforderlich ist).
+0

Danke, ich schaue mir ibatis an –

2

Ich habe mir letztes Jahr SimpleORM angesehen und war sehr beeindruckt von seinem leichten No-Magic-Design.Jetzt scheint es eine Version 3 zu geben, aber ich habe keine Erfahrung damit.

0

Weder Hibernate noch Toplink (EclipseLink) basieren auf EJB, sie sind beide POJO-Persistenz-Frameworks (ORM).

Ich stimme der vorherigen Antwort: iBatis ist eine gute Alternative zu ORM-Frameworks: Volle Kontrolle über SQL, mit einem guten Caching-Mechanismus.

0

Eine andere Option ist Torque, ich sage nicht, dass es besser als jede der oben genannten Optionen ist, aber nur, dass es eine andere Option ist, um zu betrachten. Es wird jetzt ziemlich alt, aber kann einige Ihrer Anforderungen passen.

Torque

3

Ich glaube, Sie sollten einen Blick auf apache cayenne haben, die eine sehr gute Alternative zu „großen“ Frameworks. Mit seinem anständigen Modellierer wird die Lernkurve durch eine gute Dokumentation verkürzt.

1

BEA Kodo (ehemals Solarmetrischer Kodo) ist eine andere Alternative. Es unterstützt JPA, JDO und EJ3. Es ist in hohem Maße konfigurierbar und kann aggressives Vorabholen, Abnehmen/Anfügen von Objekten usw. unterstützen.

Obwohl, von dem, was Sie beschrieben haben, sollte Toplink in der Lage sein, mit Ihren Problemen umzugehen. Meistens klingt es so, als müssten Sie in der Lage sein, Objekte an die Persistenzschicht anzuhängen/zu lösen, wenn Anforderungen gestartet und beendet werden.

0

Als ich selbst nach einem Ersatz für Hibernate suchte, stolperte ich über DataNucleus Access Platform, was ein Apache2-lizenziertes ORM ist. Es ist nicht nur ORM, da es die Persistenz und den Abruf von Daten auch in anderen Datenquellen als RDBMS wie LDAP, DB4O und XML ermöglicht. Ich habe keine Nutzungserfahrung, aber es sieht interessant aus.

0

Betrachten Sie Ihr Paradigma vollständig mit etwas wie tox zu brechen. Wenn Sie Java-Klassen benötigen, können Sie das XML-Ergebnis in JDOM laden.

2

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

Es ist ein einfacher intuitiver ORM zu verwenden.

  • Verwendet JPA Annotationen für Mapping (@Entity, @OneToMany etc)
  • sitzungs API - Keine Hibernate Session oder JPA Entity-Manager
  • Lazy Loading funktioniert
  • Teilobjekt Unterstützung für mehr Leistung
  • Automatische Abfrageabstimmung über "Autofetch"
  • Federintegration
  • Große Abfrageunterstützung
  • Große Unterstützung für Batch-Verarbeitung
  • Hintergrund
  • DDL-Generation
  • Holen Sie rohe SQL verwenden können, wenn Sie (so gut wie Ibatis) wie
  • LGPL Lizenz

  • Rob.

1

nur als Referenz, warum das Design des OP ist sein größtes Problem: spanning Transaktionen über mehrere Benutzeranforderungen bedeutet, dass Sie so viele offene Transaktionen zu einem bestimmten Zeitpunkt haben kann, da es Benutzern zu Ihrer App verbunden - eine Transaktion hält Die Verbindung ist besetzt, bis sie festgeschrieben/zurückgesetzt wird. Bei Tausenden von gleichzeitig verbundenen Benutzern kann dies möglicherweise Tausende von Verbindungen bedeuten. Die meisten Datenbanken unterstützen dies nicht.

Verwandte Themen