JPA Entities und deren Beziehungen modellieren

Dieses Thema JPA Entities und deren Beziehungen modellieren im Forum "Application Tier" wurde erstellt von distortion85, 31. Okt. 2015.

Thema: JPA Entities und deren Beziehungen modellieren Hi zusammen, ich möchte mal nach einer Hilfestellungzur Modellierung meiner JPA-Entitäten und deren Beziehungen...

  1. Hi zusammen,

    ich möchte mal nach einer Hilfestellungzur Modellierung meiner JPA-Entitäten und deren Beziehungen untereinander fragen. Ich verwende als Klassennamen in meinem Projekt abstraktere Klassennamen, sodass ich das mal auf ein "besser greifbares" Beispiel ummünze.

    Ich gehe von einem Festival aus, auf dem mehrere Auftritte stattfinden. Jeder Auftritt ist dabei natürlich genau einem Festival zuzuordnen. Bei einem Auftritt werden mehrere Instrumente gespielt, dabei ist jedes Instrument einzigartig und genau einem Auftritt zuzuordnen. Ein Instrument wird nur von einem Musiker gespielt und ein Musiker spielt nur genau ein Instrument. Im Relationenmodell sehen die Beziehungen nun also so aus:

    [​IMG]

    Die Klassen haben folgende JPA-Annotationen:

    Code (Java):
    @Entity
    public class Veranstaltung implements Serializable {
    ..
    @OneToMany(mappedBy = "veranstaltung", cascade = CascadeType.ALL)
        private List<Auftritt> auftritte;
    ..
    }

    @Entity
    public class Auftritt implements Serializable {
    ..
    @ManyToOne
        private Veranstaltung veranstaltung;
    @OneToMany(mappedBy = "auftritt", cascade = CascadeType.ALL)
        private List<Instrument> instrumente;
    ..
    }

    @Entity
    public class Instrument implements Serializable {
    ..
    @ManyToOne(cascade = CascadeType.PERSIST)
        private Auftritt auftritt;
    ..
    }
    Das ganze habe ich mit einer REST-Schnittstelle versehen, die mir testweise angelegte Datenbankeinträge als JSON zurückliefert.

    Problem 1: Bei der Beziehung zwischen Instrument<-->Musiker bin ich unsicher, ob 1:n oder 1:1, da bestimmte Musiker in anderen Auftritten auch andere Instrumente spielen.
    Problem 2: Ich kann eine Veranstaltung wunderbar abfragen und sehe, welche Auftritte dazu gehören. Aber sobald ich einen bestimmten Auftritt abfrage, ist dort keine Information darüber, zu welcher Veranstaltung dieser gehört. Genau so verhält es sich mit Auftritte<-->Instrumente. Frage ich einen Auftritt ab, sehe ich welche Instrumente gespielt werden. Frage ich aber ein Instrument ab, sehe ich nicht,zu welchem konkreten Auftritt es gehört...dabei habe ich die Beziehungen ja bidirektional umgesetzt.

    Nach JPA-Spezifikation ist die Many-Seite der Owner und die One-Seite die inverse Seite. Hier besteht das Problem also dabei, dass die Abfrage der Owner-Seite nicht die gewünschten Informationen liefert. Hoffe ist verständlich, ansonsten muss ich noch etwas mehr Code posten...
    Gedankliche Hinweise?

    Grüße
     

    Anhänge:

  2. Vielleicht helfen dir diese Java-Grundlagen weiter --> *Klick*
  3. stg
    stg
    Welcher Musiker welches Instrument spielt hängt also davon ab, welchen Auftritt man betrachtet. Denkbar wäre also zum Beispiel eine weitere Enttiy "Spielt", in welcher du Instrument und Musiker abspeicherst. In der Entity "Auftritt" hast du dann eine Liste dieser "Spielt"-Einträge. Das ist jetzt nicht zu Ende gedacht, ob es wirklich genau deine Anforderungen abdeckt. Ich will nur darauf hinaus, dass du, um solche Beziehungen korrekt abzubilden, oft auf solcherlei "Hilfstabellen" zurückgreifen musst.

    Das ist aber ein grundsätzliches XML- bzw JSON-Problem bei bidirektionalen Beziehungen. Wenn du das XML/JSON automatisch generieren lässt, dann steckst du, sofern du nicht eine Richtung "weglässt" sofort in einer endlosen Rekursion fest. Je nach Anforderung kannst du aber (bei den großen bekannten APIs wie JAXB) das Standard-Verhalten überschreiben und die "andere Richtung" deines Mappings abbilden. Oder du schreibst dir da selbst was, um dein XML / JSON zu generieren.
     
  4. Das ist interessant. Das Problem mit der Rekursion ist mir begegnet und ich hatte es mit den den Annotiationen @JsonManagedReference bzw @JsonBackReference unterbunden.

    Ich benutze derzeit Jackson, soweit ich weiß ist JAXB nur für XML?
    Deinen Lösungsansatz verstehe ich so,dass ich mir die Jackson-Klassen nehme und eigene Klassen davon ableite und diese anpasse. So meinst du das,oder?
    Danke erstmal für diesen wertvollen Hinweis.
     
  5. stg
    stg
    Eigentlich ja, aber ob man mit Hilfe der über die Annotationen gelieferten Metainformationen nun XML oder einen JSON-String generiert ist ja nahezu egal. Und daher wird auch genau das gerne gemacht. Siehe zum Beispiel hier:
    http://www.adam-bien.com/roller/abien/entry/jaxb_json_pojo_serialization_example
    http://blog.bdoughan.com/2013/03/moxys-xmlinversereference-is-now-truly.html

    Das ist auch ein richtiger Ansatz von mehreren möglichen. Vielleicht fehlt dir einfach das letzte Stückchen. Speziell für bidirektionale Relationen mit Jackson kannst du auch mal hier weiterlesen:
    http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
     
  6. Ich führe mir die Quellen erstmal zu Gemüte! Danke
     
  7. Danke für die Quelle, nach einigem Studieren und Probieren habe ich gemerkt, dass es der falsche Weg ist, an der JSON-Ausgabe rumzutüfteln. Eine bessere Lösung wäre ja, schon in der Datenbankschicht die passenden Queries abzusetzen. Und nicht das JSON nachher als Rückgabe der REST-Schnittstelle nach den gewünschten Informationen zu parsen.
    Die Beziehung Instrument<--->Musiker habe ich nun auf n<--->1 festgelegt.
    Nun interessiert mich folgender Fall: Wie setze ich über die JPQL eine Query ab, die mir alle Instrumente zurückgibt, die vom Musiker X während der Veranstaltung Y gespielt werden?
    Scheint ziemlich komplex über mehrere Tables, ich hatte so etwas versucht:

    Code (Text):
    SELECT v, a, i from Veranstaltung v, Auftritt a, Instrument i WHERE i.Musiker.id=<Id_des_Musikers> AND v.id=<id_der_veranstaltung>
    Funktioniert leider noch nicht so, wie ich das gerne hätte...
     
  8. stg
    stg
    Da musst du schon konkreter werden, wenn du dir Hilfe erhoffst.
     
  9. Du solltest dir mal die Grundlagen durchlesen. JPQL funktioniert mit den Attributnamen / Beziehungen aus deinem Datenmodell, z.B.
    Code (Text):

    from Instrument i
    inner join i.musiker m
    inner join i.auftritt a
    inner join a.veranstaltung v
    where m=:musiker and v=:veranstaltung

    query.setParameter("musiker", m);
    query.setParameter("veranstaltung", v);
     
     
  10. KOSTENLOSES Java-Grundlagen Training im Wert von 39 € Sichere dir hier den kostenlosen Zugriff auf umfangreiches Java-Know How und starte richtig durch!