Vererbung Mapping mit JPA / Hibernate

8

Dies ist eine ziemlich lange (nicht allzu komplexe) Designfrage, also bitte, bitte. Ich versuche ein Person / Rollen-Management-System mit POJOs und JPA zu implementieren. Ich bin ziemlich neu in ORM und das ist meist ein Kartierungsproblem.

Ich arbeite als POJOs und bin mit der API auf Aufrufer-Ebene vertraut, möchte sie aber jetzt in einer Seam-Umgebung mit JPA oder Hibernate in einer Datenbank abbilden.

Meine Implementierung basiert auf den Decorator (GoF) und Person Role Object Mustern (Baumer / Riehle et al). Alle Rollen sind fest codiert, und das Hinzufügen neuer Rollen zur Laufzeit wird nicht unterstützt, da Codeänderungen zur Erweiterung des Verhaltens erforderlich wären. Ich würde Benutzergruppen verwenden, um Sicherheit und Berechtigungen zu implementieren.

Es gibt eine Personenschnittstelle mit Methoden der Rollenverwaltung, wie z. B. addRole (), removeRole (), hasRole (), getRole (), getRoles (). Die konkrete Implementierung wird von einer PersonImpl-Klasse bereitgestellt.

Es gibt eine abstrakte Klasse Role, die auch die Person-Schnittstelle (für Dekorator-Substitutionsäquivalenz) und eine RoleImpl-Klasse implementiert, die sie erweitert. Die Role-Klasse enthält einen Verweis auf eine Personeninstanz und verwendet sie, um Methoden- / Eigenschaftsaufrufe auf der Personenschnittstelle zu bedienen, was bedeutet, dass alle Unterklassen von Role mit der Person-Schnittstelle umgehen können. Der Rollenkonstruktor nimmt das Personenobjekt als Parameter.

Dies sind die Schnittstellen / Klassen:

%Vor%

Dieses Diagramm zeigt die Klassenbeziehungen:

(Wenn Sie das Diagramm nicht inline sehen können, sehen Sie es hier über yUML )

Ich würde diese Klassen wie folgt verwenden:

%Vor%

Da die Rolle-Klasse auch die Person-Schnittstelle implementiert, kann ich auch tun:

%Vor%

Die Fragen, die ich habe, sind:

(a) Ist diese Implementierung unnötig kompliziert und wenn ja, was wäre ein einfacherer Ansatz? Beachten Sie, dass dies in einer nicht-trivialen Geschäftsanwendung und nicht in einem kiddy-Projekt geschieht, und ich denke, dass das Rollen-Subclassing wichtig ist, um das Verhalten in Fällen wie Mitarbeiter, Manager usw. zu nutzen.

(b) Wie stelle ich dies in JPA / Hibernate dar?

(c) Kann es zugeordnet werden, sodass ich auch das Seam Identity Management nutzen kann? (Meine Definition von Rolle ist eindeutig nicht analog zu Seams)

(d) Wenn ich eine Mapping-Strategie für Tabellen-Unterklassen (InheritanceType.JOINED) verwende, ordne ich PersonImpl als PERSONS und RoleImpl als ROLES-Tabellen ab und ordne jede Unterklasse von RoleImpl (z. B. Employee und Parent) ihren zu eigene Tische als MITARBEITER und ELTERN.

Ich hätte dann eine @ ManyToMany-Beziehung zwischen PERSONS und ROLES (in der Rollensammlung in PersonImpl) mit der Join-Tabelle PERSON_ROLES.

Nun besteht das Problem darin, dass die Tabellen EMPLOYEES und PARENTS nur die Referenz ROLE_ID haben, da die Vererbungs-Mapping-Strategie sie offensichtlich als Erweiterungen von Rollen (ROLES) betrachtet, während ich sie als Zusatz zu PERSON_ROLES benötige USER_ID + ROLE_ID-Schlüssel, der ordnungsgemäß aufgelöst werden muss, oder mindestens die USER_ID.

Ich würde eine normalisierte Datenbank mit der damit verbundenen Abhängigkeit von zusätzlichen Joins bevorzugen als eine denormalisierte Datenbank, die schwer zu pflegen ist und wahrscheinlich eine Tonne ungenutzter und irrelevanter Felder zusammenfaßt, weshalb ich denke, dass Tabelle für Unterklasse die ist Weg zu gehen.

Oder ist in diesem Szenario eine Tabellen-pro-Klasse-Hierarchie (InheritanceType.SINGLE_TABLE) mit einer Diskriminatorspalte OK (aus Sicht der Datenbankpflege)? Beachten Sie, dass einige Rollen wahrscheinlich Dutzende von Eigenschaften / Feldern haben.

(e) Gibt es eine bessere Alternative zu diesem Design?

Ich würde mich sehr über Ideen / Vorschläge freuen.

    
alan-p 13.07.2010, 16:16
quelle

1 Antwort

6

Wie gesagt

  

Also bitte bitte mit mir

Also wird meine Antwort darauf basieren, was Sie gesagt haben

  

Alle Rollen sind fest codiert ... Es gibt eine abstrakte Klasse Role ...

Wenn es eine AbstractRole-Klasse gibt, nehme ich an, dass einige in der AbstractRole-Klasse definierte Eigenschaften von allen Unterklassen übernommen werden

%Vor%

Now Employee (Derselbe Ansatz wird von Parent und Student verwendet)

%Vor%

Aber welche Vererbungsstrategie zu verwenden ???

InheritanceType.JOINED

  • Unterklassen haben eine komplexe Zuordnung: viele Eigenschaften, andere Beziehungen wie @OneToMany, @OneToOne, @ManyToMany und so weiter
  • Wenn Sie Hibernate als JPA-Provider verwenden, beachten Sie, dass Discriminator-Spalte nicht unterstützt wird. Siehe hier
  • Eine einfache Abfrage verbindet alle für jede Unterklasse definierten Tabellen. Vielleicht möchten Sie nur eine Unterklasse abrufen, und Sie werden Leistungsprobleme feststellen. Hier wird eine Problemumgehung angezeigt.

InheritanceType.SINGLE_TABLE

  • Unterklassen haben eine einfache Zuordnung. Nicht so viele Eigenschaften und minimale Anzahl anderer Beziehungen
  • Auflösung der konkreten Klasse zur Laufzeit
  • Es behandelt viele Nullable-Spalten, wenn alle Unterklassen die gleiche Tabelle
  • teilen
  • Schnellere Leistung

Sehen wir uns jetzt

an
  

Es gibt eine Person mit Methoden zur Rollenverwaltung wie zB addRole (), removeRole (), hasRole (), getRole (), getRoles (), unter anderem

Nun, wenn ich etwas wie addRole -Methode sehe, nehme ich an, dass Person entweder eine @ OneToMany- oder eine @ManyToMany-Beziehung mit der AbstractRole-Klasse hat. Ich weiß, ich weiß ... Sie haben @ManyToMany Beziehung, aber ich rate wirklich Sie teilen Ihre @ManyToMany in @ OneToMany - @ManyToOne Beziehung. Siehe hier wie man

%Vor%

Und schließlich

  

Kann es gemappt werden, damit ich auch Seam Identity Management nutzen kann

Mit Seam Identity Management können Sie Ihr eigenes Verhalten implementieren, unabhängig davon, ob Sie JPA verwenden oder nicht .

%Vor%

Und definieren Sie Ihre Authentifizierungsmethode in /WEB-INF/components.xml

%Vor%

Über Ihre Zuordnung Es hängt von Geschäftsanforderungen, Kundenbedürfnissen usw. ab, aber ich denke, es kann einfacher sein, wie oben gezeigt.

Viel Glück!

    
Arthur Ronald 14.07.2010, 03:48
quelle

Tags und Links