[JPA-Neuling] - JPA 2 und dynamische Entity-Typen/DB-Schemata

Sebastien

Mitglied
Hallo Java-Forum Gemeinde,

als JPA-Anfänger habe ich mir die JPA2-Grundkonzepte via Spezifikation sowie einem Apress-Fachbuch erarbeitet und, zumindest für den allgemeinen Fall bestehend aus nur statischen(!) Typen, weitesgehend verstanden.
Arge Verständnisprobleme bereitet mir allerdings mein dynamisches(!) Anwendungsszenario, und ich frage mich gerade, ob dieses überhaupt gut mit JPA2 realisierbar ist?!? -- Vielleicht könnt ihr mir da mit euren JPA(2)-Erfahrungen weiterhelfen.

Mein Szenario (vereinfacht) ist wie folgt:
Angenommen eine JEE6-basierte Webapp soll Endanwendern erlauben Artikel zu publizieren. Die App unterstützt jederzeit einen allgemeinen Artikeltyp "Article" mit ein Paar Standard-Attribute, z.B.

- author : String
- pubDatetime : String oder own.DateTime
- title, subtitle, articleText : String
- ...

Weiterhin soll die App einer privilegierten Endanwendergruppe gestatten, diesen allgemeinen Artikeltyp um dynamische Attribute zu erweitern, wie etwa

- articleTopic : own.ArticleCategoryEnum
- rating : Float
- comments : List<String>
- ...

Ich denke, das Prinzip dürfte damit offensichtlich und nicht einmal sehr "exotisch" sein.

* Ist ein solches dynamisches Szenario mit JPA2 realisierbar? Und wenn ja, wie könnte man das am besten bewerkstelligen?

[Entsprechende Suchanfragen im Forum ergaben 3-4 Beiträge, die in diese Richtung gehen aber leider keine für mich anwendbaren Antworten liefern.]

Vielen Dank für eure Hilfe und Tipps im Voraus.

- Sebastien
 

brauner1990

Bekanntes Mitglied
was ist den
Code:
own.DateTime
ist das
Code:
extends java.util.Date
? Wenn ja, könntest du es via einer Casting Methode machen, bzw. mit SimpleDateFormat und Date parsing
 

Sebastien

Mitglied
was ist den
Code:
own.DateTime
ist das
Code:
extends java.util.Date
? Wenn ja, könntest du es via einer Casting Methode machen, bzw. mit SimpleDateFormat und Date parsing

An dieser Stelle wollte ich mit "own.Datetime" nur die Anforderung des möglichen Einsatzes eigener, anwendungsweiter Typen veranschaulichen ... O.K., dies gerade bei einem temporalen Typ zu tun, der in Java mit 'java.util.Date/Calender/GregorianCalendar' und 'java.sql.Date/Time/Datetime' eh recht "unüberschaubar" ist, war vielleicht nicht die beste Idee.

Die Fähigkeiten von
Code:
java.util.Date
oder
Code:
java.sql.Timestamp
würden in meinem Szenario an der dortigen Stelle ausreichen.

Dennoch, vielen Dank für deinen diesbezüglichen Tipps.

Sebastien
 

Sebastien

Mitglied
das müsste gehn, zumindest mit EclipseLink (der Teil gehört aber sicher nicht zum Standard).

Schau mal hier (unten):

EclipseLink/Examples/JPA/Dynamic - Eclipsepedia

//EDIT

Ne andere Möglichkeit wäre eine Map (aber nicht streng typisiert):

EclipseLink/Development/JPA2.0/Extended Map support - Eclipsepedia

Hallo zusammen,

zunächst einmal, vielen Dank für die guten Links.

A) Bzgl. "Dynamic Persistence":
Dieses Feature bei EclipseLink (ich glaube Hibernate bietet auch Ähnliches) kannte ich zwar bereits, hatte ich aber (ggf. zu schnell!?) beiseite gelegt, weil -- wenn ich die Thematik richtig verstanden habe -- es nicht so ganz auf mein Problem passt:

  • "Dynamic Persistence" soll IMHO erlauben, aus Java heraus auf bereits existierende Tabellen(schemata) zuzugreifen, *ohne* über a priori zu definierende JPA-Entity-Klassen zu gehen. -- Also ausgehend von einer *fixen* Tabellenstruktur.
  • In meinem Problem habe ich es mit *variablen* Tabellen-Erweiterungen (ggf. auf Sekundär-Tabellen ausgelagert) zu tun, d.h. dyn. Tabellen-Strukturen, deren dynamischer Anteil in meinem Fall eine stets anwachsende (nie verringernde oder ändernde) Erweiterung der Standard-Attributen-Menge darstellt.
Ist meine Auffassung richtig, oder übersehe ich bzgl. "Dyn. Persistence" etwas Wichtiges???
Wenn ja, wie könnte damit ein möglicher Lösungsweg aussehen?

B) Bzgl. Maps:
Einige Lösungsbeispiele mit Maps aus'm Netz hatte ich mir angeschaut; das momentane Problem damit ist zweierlei:
  1. die fehlende Berücksichtigung von Attribut-Typen (fehlende Typsicherheit, wie ihr auch richtig erwähnt habt) und
  2. die Speicherung nicht-atomarer Datentypen unter einem Mapschlüssel, d.h. einerseits als
    Code:
    Array
    ,
    Code:
    List
    ,
    Code:
    Set
    sowie ggf. wieder
    Code:
    Map
    typisierte Objektmengen, andererseits benutzer-definierte (oder vielleicht besser: benutzer-erweiterte) Objekttypen (z.B. 'MyArticleTypeWithComments' extends 'Article', ö.ä.).

O.K., generell könnte man mit jedem Map-Eintrag eine Struktur als Value abspeichern, die neben der String-Repräsentation des Werts (bzw. der Werte) auch die Metadaten zum Value-Typ bzw. Collection-Typ und Element-Typ festhält; Die jew. Konvertierungen und die Typsicherheit müsste dann auf App-Ebene erfolgen.
Wie das konkret aussehen könnte, weiß ich noch nicht so recht.
-- Vielleicht habt ihr ja dazu bereits eigene Erfahrungen und Tipps.

Weiterhin vielen Dank im Voraus
Sebastien
 
G

Gelöschtes Mitglied 5909

Gast
Ohne jetzt lange drüber nachzudenken,
würde ich warscheinlich eine Tabelle (ID,KEY,VALUE) machen.

Dann hast du zwar keine Typsicherheit, aber du kannst es "dynamisch" machen.

Tabellen zur Laufzeit anzulegen würde ich nicht empfehlen. Darunter leidet nicht nur die Qualität,
das ganze kannst du auch nahezu nicht testen (bzw. nur sehr stichprobenartig)

Alternativ kannst du noch eine Spalte Typ hinzufügen, die dir dann sagt wie du das ganze Parsen musst.
Als Inhalt könntest du sogar JSon/XML nehmen.
Ggf kanst du auch noch eine Spalte regex dazu machen, die einen Regulären Ausdruck über den gültigen Inhalt darstellt.

Vorteil:
- Nahezu alles Abbildbar
- Relativ gut testbar
- Nachvollziehbar

Nachteil:
- Weniger "komfort" in den Entities
- Parselogik
Nahezu alles Abbildbar.
 
M

maki

Gast
würde ich auch so machen. Tabellen Strukturen in Zuge von fachlichen Usecases zu ändern finde ich nicht ganz richtig...
Würde ich nicht so machen... zumindest nicht mit einem ORM ;)

Da tut man sich mit JDBC (oder gar iBatis?) einfacher, ein ORM ist für etwas anderes da, sehe da keine "Objekte" bzw. Typen mit Verhalten, sondern "nur" Datenstrukturen.

Nachtrag: Wenn man es genau nimmt, geht es hier auch nicht um eine relationale Datenbank, also wäre ein ORM doppelt unpassend ;)
 
Zuletzt bearbeitet von einem Moderator:

Sebastien

Mitglied
Hallo zusammen,

vielen Dank für die bis dato geäußerten Tipps.


Würde ich nicht so machen... zumindest nicht mit einem ORM ;)

Da tut man sich mit JDBC (oder gar iBatis?) einfacher, ein ORM ist für etwas anderes da, sehe da keine "Objekte" bzw. Typen mit Verhalten, sondern "nur" Datenstrukturen.


@maki: Hallo maki,

deine "eingeschränktere Sicht" auf ORM kenne ich bereits von deinem ersten, hiesigen Beitrag ;-)
Ich sehe für meinen Fall auch keine "Objekte" mit Verhalten, sondern auch "nur" Datenstrukturen, allerdings welche, die sich mit der Zeit *leicht* und nur erweiternd ändern könn(t)en!!!

Augenscheinlich sind dynamische O/R-Mappings auch O/R-Mappings, wenngleich sie nicht zum primären Anwendungsfall gehören!

Es ist klar, welche initiale/primäre Intention sie verfolg(t)en (d.h. die reine Anbindung der existierenden Strukturen; also den rein statischen Fall), jedoch gibt es -- speziell seit der Web 2.0 Ära -- zunehmend mehr "Nachfrage" für O/R-Mappings mit einem zumindest kleinen Anteil an Dynamic. Wer sagt denn, dass die DB-Strukturen sich zu keiner Zeit nachträglich -- sei es mit oder ohne die Einwirkung des OO-Programms -- ändern dürfen?
Ich denke, im kleinen und vertretbaren Umfang sollte dies schon legitim sein, zumal SQL in der DDL auch die Möglichkeiten zur nächträglichen Modifikation anbietet (die man von irgendeinem Programm nutzen kann).
Die eigentliche Frage stellt sich dahingehend, inwieweit das eingesetzte O/R-Framework Konstrukte anbietet, die dem Benutzer die erforderlich werdenden Mapping-Anpassungen weitestgehend abnehmen kann.

-- Oder wieso glaubst Du bietet EclipseLink (und ich glaube auch Hibernate) schon jetzt einige Funktionalität, die genau in diese Richtung geht?!? Doch wohl nicht weil sie keine ORM-Frameworks mehr sein wollen, oder? ;-) ;-)

@all: Siehe hierzu die zwei Links, die ich auf Anfrage vom EclipseLink-Forum erhalten habe:

1. EclipseLink/DesignDocs/Extensibility - Eclipsepedia
2. EclipseLink/Examples/JPA/Extensible - EclipsepediaEclipseLink/Examples/JPA/Extensible - Eclipsepedia

Fazit (IMHO): Alles eine Frage der angestrebten Framework-Mächtigkeit und dem damit einhergehenden Einsatzradius.


Nachtrag: Wenn man es genau nimmt, geht es hier auch nicht um eine relationale Datenbank, also wäre ein ORM doppelt unpassend ;)

Mit welcher Backend-Technologie würdest Du (würdet ihr) denn dann dieses Problem -- sagen wir mal, wenn es sehr, sehr dynamisch *wäre* -- lösen?

Vielen Dank.
- Sebastien
 
G

Gelöschtes Mitglied 5909

Gast
Tabellen ändern sich normalerweise durch Releases, aber nicht zur "Laufzeit". Ich weiß nicht wie du das ordentlich testen willst.

Irgendwie wird das sicher alles gehn, aber irgendwie ist irgendwie zu wenig Qualitätsorientiert.
 
M

maki

Gast
Sebastien,

will dir nix ausreden, wollte dir nur sagen dass ein ORM dazu da ist Objekte zu Relationalen Datenbanken zu mappen, und dass du dir wohl leichter tust wenn du den dynamischen Teil nicht per ORM verwaltest.

Web 2.0 hin oder her, jedes Werkzeug hat seinen Einsatzweck, weder wirst du dyn. Attribute zu deinen Objekten hinzufügen (im OO Sinn), noch wirst du die dyn. felder mit einer relationen Semantik ausstatten können (RI).
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Hibernate Dynamische Tables Data Tier 6
OnDemand Vorgehen DB /Entity Data Tier 2
A Entity Manager Data Tier 4
erdmann Entity-Services ein Antipattern? Data Tier 3
S JPA Cascade: Entity nur speichern, wenn sie nicht schon existiert Data Tier 0
E JPA Session.delete einer Entity wird nicht ausgeführt Data Tier 2
G JPA: Entity Klasse @JoinColumns Problem Data Tier 2
G EJB NoSuchEJBException Zugriff auf Entity Data Tier 6
Landei JPA - Entity mit Maps Data Tier 2
H [Hibernate] Unknown Entity Data Tier 3
G JPA/ Eclipselink: (Alte) Kopie einer Entity? Data Tier 6
J Servlet mit eigenem Entity-Manager innerhalb von Seam-Projekt Data Tier 3
lumo Hibernate - entity class not found Data Tier 5
J synchronisierte Zugriffe auf die gleiche Entity (JPA) Data Tier 19
LCS Entity mit variablen Tabellennamen Data Tier 3
D jpq entity life cycle - insert, update... Data Tier 5
A @org.hibernate.annotations.Entity(dynamicUpdate=true, optimisticLock=OptimisticLockType.ALL) Data Tier 2
T [JPA] Update Entity in Entity Data Tier 2
byte Hibernate: Criteria & SubQuery - Unknown Entity null Data Tier 1
Final_Striker EJB3: Entity nach persist wiederfinden Data Tier 8
N Entity-Object muss auf Client aktualisiert werden Data Tier 13
0 org.hibernate.MappingException: Unknown entity Data Tier 8
K Hibernate: Unknown entity Data Tier 7

Ähnliche Java Themen


Oben