MyBatis vs. JPA: Es gibt keine schlechte Technologie.

„Was genau ist dieses Projekt eigentlich?“

Das Projekt in meiner aktuellen Firma ist so etwas wie ein „Frankenstack“. MyBatis und JPA existieren im selben Projekt nebeneinander. Das Problem war nur: Die „Schöpfer“, also die ursprünglichen Teammitglieder, die diesen Code geschrieben hatten, waren längst alle aus der Firma weg.

Wir Zurückgebliebenen, also das aktuelle Team, waren verwirrt. Es gab kein einziges Dokument, das erklärte, nach welchen Kriterien diese Technologien gemischt worden waren. Dadurch wurde die Lage nur immer chaotischer.

Am Ende lief es darauf hinaus, dass innerhalb desselben Services manche Leute für ähnliche Funktionen XML wühlten, während andere Entities modellierten. Das Ganze war zu einer merkwürdigen Form technischer Anarchie geworden. Das Projekt verwandelte sich immer mehr in ein Monster, das kaum noch wartbar war, bis schließlich ein Meeting einberufen wurde.

„Lasst uns den Tech-Stack auf eine Technologie vereinheitlichen.“

Technologien ohne klare Regeln zu mischen ist keine Freiheit, sondern nur Verwirrung.

„JPA ist doch zu langsam, oder?“

Die Stimmung im Meeting war angespannt. Vor allem Kolleginnen und Kollegen, die an MyBatis gewöhnt waren, lehnten eine Vereinheitlichung auf JPA stark ab. Ihr zentrales Argument war die Geschwindigkeit.

„Erinnert ihr euch nicht mehr an die Statistikseite, die wir mit JPA gebaut haben und die 20 Sekunden zum Laden gebraucht hat? Wenn wir das SQL direkt schreiben, kommt das Ergebnis in einer Sekunde. Ein Blackbox-Tool, das wir nicht voll kontrollieren können, ist riskant.“

Tatsächlich brauchten manche Logiken allein für das Laden der Daten mehrere Dutzend Sekunden. Aber ich war überzeugt, dass das kein Problem der Technologie war, sondern ein Problem der Erfahrung. Noch im Meeting klappte ich meinen Laptop auf und zeigte den berüchtigten „20-Sekunden-Code“.

Der Code war katastrophal. Es wurde ein List<Entity> abgefragt, und jedes Mal, wenn die Schleife ein verknüpftes Objekt berührte, wurde die Datenbank erneut angesprochen, Stück für Stück. Ein klassisches N+1-Problem.

„Das bedeutet nicht, dass JPA langsam ist. Es bedeutet, dass wir JPA ineffizient arbeiten lassen. Schaut her.“

Ich setzte spontan einen Fetch Join ein und reduzierte die Abfrage auf einen einzigen Zugriff. Nach dem Deployment sank die Ladezeit von 20 Sekunden auf 1 Sekunde. In diesem Moment veränderte sich der Blick meiner Kolleginnen und Kollegen.

Bevor man dem Werkzeug die Schuld gibt, sollte man zuerst die Anleitung lesen.

Unerwartete Erkenntnis: kein Mischmasch, sondern ein Hybrid

Nachdem das Missverständnis rund um JPA ausgeräumt war, hätten wir dann einfach alles auf JPA vereinheitlichen sollen? Wenn man genauer hinschaute, war auch das nicht die richtige Antwort.

Komplexe Statistikabfragen oder Excel-Downloads mit Hunderttausenden von Datensätzen über JPA abzuwickeln war unpraktisch: Die Kosten für die Objektabbildung waren zu hoch, und dynamische Queries ließen sich nur umständlich schreiben. MyBatis war für solche Aufgaben dagegen deutlich intuitiver und schneller. Ich fragte mich: „Wie lösen andere Firmen dieses Problem?“ Also suchte ich die halbe Nacht lang auf Google und durchforstete Tech-Blogs.

Überraschenderweise beharrten viele Technologieunternehmen gar nicht nur auf JPA. Manche nutzten QueryDSL für performante komplexe Leseabfragen, andere setzten, genau wie wir, zusätzlich auf MyBatis.

Da machte es bei mir Klick. „Ah, die Leute vor uns haben das also doch nicht gedankenlos zusammengemischt.“

Sie kannten bereits die Vor- und Nachteile der einzelnen Werkzeuge und hatten die Technologien bewusst nach Aufgaben getrennt. Das eigentliche Problem war nur, dass sie ohne Dokumentation gegangen waren und wir, die das System übernommen hatten, deshalb darüber stritten, warum man es nicht vereinheitlicht hatte.

Über die Grenzen von JPA hinaus: QueryDSL und Projection

Dann stellte sich die nächste Frage: Können wir MyBatis entfernen und dieses Problem nur mit Technologien aus dem JPA-Ökosystem lösen? Genau hier kommen QueryDSL und Projection ins Spiel.

// 1. Interface, das nur die benoetigten Felder definiert (kein DTO noetig)
public interface DailyStat {
    String getDate();
    Long getTotalSales();
}

// 2. Abfrage ueber QueryDSL oder ein JPA-Repository
// Es werden nur diese beiden Spalten aus der DB geSELECTet, also so schnell wie MyBatis.
List<DailyStat> stats = repository.findDailySales();

Als ich diese Werkzeuge verstanden hatte, gab es deutlich weniger Grund, in die XML-Hölle von MyBatis zurückzukehren. Auch im JPA-Ökosystem lassen sich schließlich sehr performante Queries bauen.

Praxis-Tipp: Nicht streiten, sondern sinnvoll koexistieren lassen

Am Ende entschied sich unser Team nicht für eine bedingungslose Vereinheitlichung, sondern für eine „Koexistenz mit klaren Prinzipien“. (Langfristig wollten wir allerdings in Richtung QueryDSL gehen.)

Interessant ist, dass diese Überlebensstrategie, für die wir uns entschieden haben, also „Schreiben (Command) mit JPA, Lesen (Query) mit spezialisierten Werkzeugen“, aus architektonischer Sicht eine sehr einfache Form des CQRS(Command and Query Responsibility Segregation)-Musters ist.

Man muss die Datenbank dafür nicht groß aufsplitten. Schon die Philosophie, Verantwortlichkeiten für Commands und Queries auf Code-Ebene zu trennen, macht ein Projekt deutlich sauberer.

Zum Schluss: Technologie ist nicht schuld

Wir diskutieren oft: „JPA ist das Beste“ oder „Nein, MyBatis funktioniert in der Praxis viel besser“. Aber was ich aus dieser Erfahrung gelernt habe, ist: Es gibt keine schlechte Technologie. Es gibt nur Situationen, in denen man eine Technologie für den falschen Zweck einsetzt.

JPA ist wie ein Zauberstab, aber wenn man den falschen Spruch aufsagt, explodiert er. MyBatis ist wie ein robuster Hammer, aber er kann dazu führen, dass alles wie ein Nagel aussieht.

Wenn euer Team gerade wegen Legacy-Code oder wegen unterschiedlicher Technologievorlieben aneinandergerät, haltet kurz inne. Vielleicht steckt in diesem Chaos das tiefe Nachdenken früherer Entwicklerinnen und Entwickler. Es zu finden und in klare Regeln zu verwandeln, genau das ist der Weg zu einem wirklich starken Entwicklungsteam.

Schreibe einen Kommentar