M-zu-N-Beziehungen und JPA

vorhergehende Artikel in: Komponenten sQLshell Datenbanken
05.04.2022

Ich habe bereits darüber berichtet, dass die sQLshell ein neues Plugin anbietet, das aus bestehenden Datenmodellen in Datenbanken JPA-Entityklassen generieren kann.

Neulich bin ich bei meinen Tests über eine Eigenart gestolpert, die mich einige Stunden des Suchens gekostet hat, bis ich die Ursache dafür fand:

Ich experimentierte mit M-zu-N-Beziehungen (in JPA mittels @ManyToMany Annotationen modelliert) in meinem veröffentlichten Projekt für Tests für dieses neue Plugin.

Konkret wollte ich bei drei Klasen A, B und M bei denen A und B über eine Mapping-Tabelle M mittels einer solchen M-zu-N-Beziehung verknüpft waren neue Entities hinzufügen und diese neuen Entities in den Tabellen A und B entsprechend verknüpfen.

Das funktioniert mit einer explizit als Entity mopdellierten Mappingtabelle M zum einen über das Persistieren entsprechender Entities in M. Zum anderen müsste es eigentlich möglich sein, ein Entity zum Beispiel für A zu persistieren, anschließend eines für B zu erzeugen, dessen Getter für die verknüpften Entities in A aufzurufen und diesem Ergebnis (einer Collection) dann das neu erzeugte A-Entity hinzufügen und dieses anschließend ebenfalls zu persistieren. Dadurch sollte automatisch eine entsprechende Zeile in der Mappingtabelle M auftauchen.

Genau das funktionierte jedoch nicht. An dieser Stelle noch einige Hintergrundinformationen: A, B und M hatten jeweils ein mittels @Id annotiertes Feld, das letztlich der Primärschlüsselspalte in der Tabelle entsprach. Jedes dieser Felder war darüber hinaus mit einer Annotation @GeneratedValue und der strategy GenerationType.AUTO versehen, die dafür sorgt, dass man beim Erzeugen von Entities aus der Anwendung heraus keine Primärschlüssel manuell festlegen muss. Das funktionierte hervorragend für das explizite Anlegen von Entities jeweils in den Tabellen A, B und M.

Wenn ich jedoch die oben skizzierte Variante für das Anlegen einer Relation versuchte, bei der die Entity bzw. die neue Zeile in M implizit erzeugt werden sollte, wurde jeder dieser Versuche mit einem Fehler quittiert, der letztlich aussagte, dass es nicht erlaubt sei, in die Primärschlüsselspalte von M eine NULL einzutragen.

Nach schier endloser Sucherei und immer verzweifelterem Herumprobieren fand ich schließlich die Lösung: Ich hatte glücklicherweise ein zweites Datenmodell zur Hand, in dem ebenfalls eine M-zu-N-Beziehung bestand. In diesem Datenmodell funktionierte die implizite Erzeugung des Entities der Mappingtabelle wie gewünscht. Nachdem ich mir sicher war, dass die Entityklassen bis auf die Namen identisch annotiert waren, untersuchte ich die Datenbanken. In beiden Fällen handelte es sich um Postgres mit der identischen Version 42.2.18 des JDBC-Treibers.

Allerdings entdeckte ich einen Unterschied im Datenmodell: Dort, wo die implizite Erzeugung des Entity funktionierte war die Primärschlüsselspalte vom Typ SERIAL, während sie dort, wo es nicht funktionierte vom Typ INTEGER war. Nachdem ich diesen Fakt anglich, funktionierte plötzlich auch dort alles, wo es sich vorher standhaft geweigert hatte.

Die Erkenntnis also: Arbeitet man mit JPA bzw. der Implementierung hibernate core in der Version 5.4.23.Final, so sollte man darauf achten, dass die Primärschlüsselspalten in Mapping-Tabellen für M-zu-N-Beziehungen immer vom Typ SERIAL sind.

Das brachte mich dazu, die Versionen schleunigst anzupassen - immerhin stammten die benutzten noch aus dem Jahr 2020. Also änderte ich die Abhängigkeite wie folgt: Ich nutzte den Postgres-Treiber in Version 42.3.3 und Hibernate in Version 5.6.7.Final.

Jedoch blieb auch in den neueren Versionen das Problem exakt so bestehen.

Alle Artikel rss Wochenübersicht Monatsübersicht Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • 8TB Raid5 mit Raspberry Pi

    25.04.2020

    Ich habe mir neulich überlegt, ob man einen Pi als Raid benutzen könnte - aber nicht mit dem ewig gleichen Setup mit 4 USB-Sticks...

    Weiterlesen...

Neueste Artikel

  • Watch David Byrne Lead a Massive Choir in Singing David Bowie’s “Heroes”

    Durch die Seite Open Culture bin ich auf diesen spektakulären Auftritt aufmerksam geworden:

    Weiterlesen
  • Zufälliges Füllen der Ebene

    Ich fand neulich einen sehr interessanten Artikel Zum Thema der algorithmischen Erzeugung von dekorativen (obwohl - das liegt im Auge des Betrachters) Bildern.

    Weiterlesen
  • Sicherheit beim Fernzugang per SSH

    Ich habe vor einiger Zeit bereits zwei Vorträge gestaltet und dafür meine Ideen zur unkomplizierten Erstellung von Präsentationen genutzt - nun ist ein weiterer hinzugekommen.

    Weiterlesen

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen Codeberg-Repositories findet man hier.