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



## Sebastien (1. Mrz 2011)

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


----------



## maki (1. Mrz 2011)

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


Doch, das ist "exotisch" zumindest für ein ORM.


----------



## brauner1990 (1. Mrz 2011)

was ist den 
	
	
	
	





```
own.DateTime
```
 ist das 
	
	
	
	





```
extends java.util.Date
```
 ? Wenn ja, könntest du es via einer Casting Methode machen, bzw. mit SimpleDateFormat und Date parsing


----------



## Sebastien (1. Mrz 2011)

brauner1990 hat gesagt.:


> was ist den
> 
> 
> 
> ...



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 
	
	
	
	





```
java.util.Date
```
 oder 
	
	
	
	





```
java.sql.Timestamp
```
 würden in meinem Szenario an der dortigen Stelle ausreichen.

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

Sebastien


----------



## Gelöschtes Mitglied 5909 (1. Mrz 2011)

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


----------



## Sebastien (2. Mrz 2011)

> das müsste gehn, zumindest mit EclipseLink (der Teil gehört aber sicher nicht zum Standard).
> 
> Schau mal hier (unten):
> 
> ...



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:

die fehlende Berücksichtigung von Attribut-Typen (fehlende Typsicherheit, wie ihr auch richtig erwähnt habt) und
die Speicherung nicht-atomarer Datentypen unter einem Mapschlüssel, d.h. einerseits als 
	
	
	
	





```
Array
```
, 
	
	
	
	





```
List
```
, 
	
	
	
	





```
Set
```
 sowie ggf. wieder 
	
	
	
	





```
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


----------



## Gelöschtes Mitglied 5909 (3. Mrz 2011)

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.


----------



## ARadauer (3. Mrz 2011)

> würde ich warscheinlich eine Tabelle (ID,KEY,VALUE) machen.


würde ich auch so machen. Tabellen Strukturen in Zuge von fachlichen Usecases zu ändern finde ich nicht ganz richtig...


----------



## maki (3. Mrz 2011)

ARadauer hat gesagt.:


> 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


----------



## Sebastien (4. Mrz 2011)

Hallo zusammen,

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




maki hat gesagt.:


> 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.




maki hat gesagt.:


> 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


----------



## Gelöschtes Mitglied 5909 (4. Mrz 2011)

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.


----------



## maki (4. Mrz 2011)

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).


----------

