Loading...

@Transaction Around Test

13. November 2023
3 Minuten Lesezeit
Beitrag teilen:

Hi,

Mir kribbelte es in den Fingern. Direkt zu Beginn von Thorben Janssens Session “Das große Java Persistence Q&A”.

Die erste Frage war (sinngemäß):

“Im vorherigen Talk (etwas mit JPA) wurde gesagt man solle an jeden Test @Transactional schreiben. Dadurch werden die Daten nach dem Test automatisch zurückgerollt. Wir haben das diskutiert und sind uns uneinig. Was ist deine Empfehlung?”

Thorbens Antwort machte mich nervös. Er antwortete (auch sinngemäß) mit einer Gegenfrage:

“Ist denn dein Produktionscode innerhalb einer Transaktion? Wahrscheinlich schon. Deswegen solltest du auch im Test eine Transaktion nutzen.”

Die Message also: Ja. Bitte @Transactional verwenden.

Ich wurde richtig nervös bei der Empfehlung. Diese Idee habe ich so oft scheitern gesehen.

Hier meine Gründe:

  1. Ein Test ist ein Client : Er soll den Produktivcode so aufrufen, wie es ein echter Client tut. Es ist unwahrscheinlich, dass der gesamte Test - samt assert - innerhalb einer Transaktion liegt.
  2. Der umgreifende Persistence Context könnte meine Ergebnisse verändern :
    • Vielleicht hat die Datenbank durch einen Trigger in ein Feld geschrieben.
    • Oder ich öffne in meinem Applikationscode mehrere Transaktionen, was in einer übergreifenden Transaktion nicht nachgestellt wird.
    • Unmanaged Entities könnten zwischen verschiedenen Persistence Contexten umhergereicht werden, was auf Produktion zu Fehlern führen kann.

Ich möchte im Standard bloß keine Transaktion um den Test. Das habe ich bereits 2020 in meinem Talk (k)lean JPA erzählt.

Nach dem Talk bin ich zu Thorben und habe es mit ihm und dem Fragesteller diskutiert. Und die Argumentation war schlüssig. Thorben hat noch Beispiele genannt, die für und gegen @Transactional sprechen.

Es ist also wie immer - it depends.

Aber wir waren uns einig. Im Default sollte es keine Transaktion geben.

JPA ist kompliziert. Erst wenn man die Basics verstanden hat, machen die Fehler und das Verhalten, das man beobachtet, Sinn. Die Basics sind aber gar nicht so klein.

Hast du eigentlich schon mal den JPA Standard gelesen? Nein? Dann hol das unbedingt nach!

Und schau dir meinen Talk (k)lean JPA an. Auch wenn er damals Kotlin im Fokus hatte: All die Probleme, die ich anspreche, hast du auch mit Java.

Manche erlebst du nur seltener. Java hat andere Defaults. Zum Beispiel sind in Java per default alle Klassen open und nicht final. Daher hast du wahrscheinlich noch nicht erlebt, dass lazy fetching aus “unerklärlichen Gründen” nicht funktioniert.

Was hältst du von @Transactional an Tests? Hast du dir darüber schon mal Gedanken gemacht? Schreib mir gerne!

ps. Thorben ist ein super Typ und weiß wovon er redet. Wenn du lieber nicht den JPA Standard lesen möchtest und eine Schulung brauchst, dann melde dich bei ihm !

pps. Ich habe auf der W-JAX meinen Talk “The Performance Mindset” gehalten . Es gibt seitdem ein paar neue Leser unter euch. Willkommen! Wenn du den Talk verpasst hast, dann kannst du dir die englische Version, die ich als Keynote auf der RabbitMQSummit gehalten habe auf Youtube anschauen .

wjax.jpeg

Rule the Backend,

~ Marcus

Top