Datenbank?

Wenn man fjorum bei sich zum Laufen bringen will, scheint zur Zeit das größte Problem die Datenbank zu sein.

Eine eingebettete DB für den Entwicklermodus würde das Problem lösen, dann braucht man nur Maven zu installieren, das Projekt clonen und kann loslegen.

Nun hatte ich an einer Stelle schon eine eingebette DB, nämlich H2, und die Ergebnisse waren nicht berauschend. Auch wenn alles irgendwie lief, war das System trotzdem hakelig und unbequem zu handeln. Nun würde ich gern einen neuen Anlauf mit ObjectDB versuchen, die als Objekt-Datenbank überhaupt kein relationales Schema braucht.

Ich stelle mir das so vor: In der Ninja-Config kann man zwischen verschiedenen Umgebungen (etwa wie Profile in Spring) unterscheiden, man könnte also “prod” auf PostgreSQL und “dev” auf ObjectDB zeigen lassen. Dann könnte man im Init-Hook von Ninja schauen, ob man im Dev-Mode ist, aber keine ObjectDB-Datei vorhanden ist, und für eine Initialisierung sorgen (z.B. mit einem Admin-Nutzer, mit dem man sich erst mal einloggen kann), ansonsten behält man seine die Daten.

Mit ObjectDB könnte auch ziemlich einfach Tests für die Services schreiben. Statt zu mocken setzt man einfach eine kleine Test-DB auf, die man am Ende wieder löscht.

Weiterhin bräuchte man auch keine Schema-Updates, wenn man kein PostgreSQL verwendet (was FlyWay oder Liquibase ziemlich überflüssig machen würde).

Und wenn ObjectDB eine gute Performance zeigen sollte, könnte man sogar überlegen, das als Option für kleinere Foren anzubieten, wenn der Hoster keine DB bereitstellt / zulässt.

Natürlich ist das nur die Theorie, keine Ahnung, ob das so funktioniert. Denkt ihr, das ist ein Versuch wert, oder hat da vielleicht schon jemand Erfahrungen mit?

Mkay, habe das Setup soweit hinbekommen, wie gesagt “prod”-Mode mit PostgreSQL und “dev”-Mode mit ObjectDB.

Um eine initiale Belegung bei ObjectDB hinzubekommen, habe ich erst erfolglos versucht, das über eine StartActions-Klasse zu machen. Jetzt habe ich es ganz einfach so gelöst, dass man im “dev”-Mode das magischen User/Passwort-Paar “pretty” / “please” eingeben kann, um sich einen “admin” / “admin” - Nutzer erzeugen zu lassen.

Jetzt bin ich aber in ein Problem gerannt: ObjectDB kann mit LocalDateTime nichts anfangen, die entsprechende Convert-Annotation wird ignoriert:

com.objectdb.o._RollbackException: Failed to commit transaction: Attempt to store an instance of a non persistable type java.time.LocalDateTime - field org.fjorum.models.Topic.created

Bist Du sicher, dass Du unterschiedliche DBs verwenden möchtest? Zumal dann noch relational und object. Ich könnte mir vorstellen, dass es da an einigen Stellen Unterschiede gibt, die man nicht auf den ersten Blick sieht.

Theoretisch ist alles fein, weil ObjectDB ja gerade das JPA-Interface unterstützt. Für die Anwendung ist der Unterschied also nicht sichtbar, ObjectDB hat genauso Persistence-Units, EntityManager und Krams wie ein normales ORM - sonst hätte ich gleich die Finger davon gelassen.

Praktisch hat es mit User und Categorie auch problemlos geklappt, ohne ein µ an den Entities ändern zu müssen. Es war auch recht cool, wie man ohne irgendwelche Installation oder Schemakrams loslegen konnte. Ich bin ziemlich sicher, dass es bei den anderen Entities sofort laufen würde, wenn ich LocalDateTime in Timestamp oder so ändern würde - aber wer sagt uns, dass wir nicht mit dem nächsten Datentyp in die gleiche Sackgasse rennen?

Habe erst mal einen recht gnatzigen Beitrag in ihr Forum geschrieben: Auf der einen Seite sagen sie, dass JPA halt LocalDateTime noch nicht unterstützt (pochen also auf Kompatitibilität), auf der anderen Seite unterstützen sie @Convert nicht (was JPA-Standard ist). Mal sehen, was sie antworten…

Wenn Hoffnung auf eine Lösung erkennbar ist, würde ich mein Zeugs erst mal in einen Branch committen.

Edit

Ups, ich sehe gerade, dass ich für mehr als 10 Entity-Klassen eine kommerzielle Lizenz brauche. Damit wäre ObjectDB höchstens in der Anfangsphase interessant, das Limit werde ich wohl recht schnell reißen. Ich schaue nochmal, ob es noch was ähnliches gibt, das Konzept hat mir schon ziemlich gefallen.

Wo ist fas Problem mit MySQL?

Hatte mal als Unregistriert über Probleme mit der DB gepostet.

Habe diesen Teil jetzt in sofern gelöst das ich PostgreSQL von meinem System entfernt habe.

Ich wollte mir schon eine Zeit lang Docker.io ansehen. Hatte zuvor schon den eine oder anderen Blick auf Vagrant in Kombination mit Chef, Puppet geworfen.
Das sind Tools um die Systemkonfiguration zu automatisieren.

Lange Rede kurzer Sinn, habe ich mir ein Dockerfile erstellt, dass mir ein System mit einer PostgreSQL-DB, der entsprechenden Konfiguration und dem Schema bereitstellt.
Der Vorteil daran ist, dass das System unangetastet bleibt, das ganze Reproduzierbar bleibt, etc. pp. Unter Linux läuft das mehr oder weniger automatisch und kann die enthaltenen Virtualisierungsmöglichkeiten nutzen. OSX und MSW brauchen Boot2docker, ein minimales Linux, das die Docker-Container ausführt.

Dockerfile
[SPOILER]

FROM ubuntu
MAINTAINER admin@fjorum.com

RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8 

RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list

RUN apt-get update && apt-get install -y python-software-properties software-properties-common postgresql-9.3 postgresql-client-9.3 postgresql-contrib-9.3

USER postgres

ADD ./db/fjorum_db.sql /tmp/fjorum_db.sql 

RUN    /etc/init.d/postgresql start &&\
    psql --command "CREATE USER fjorum WITH SUPERUSER PASSWORD 'fjorum';" &&\
    createdb -O fjorum fjorum &&\
    psql --file="/tmp/fjorum_db.sql" --dbname=fjorum

RUN echo "host all  all    0.0.0.0/0  md5" >> /etc/postgresql/9.3/main/pg_hba.conf

RUN echo "listen_addresses='*'" >> /etc/postgresql/9.3/main/postgresql.conf

EXPOSE 5432

VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

CMD ["/usr/lib/postgresql/9.3/bin/postgres", "-D", "/var/lib/postgresql/9.3/main", "-c", "config_file=/etc/postgresql/9.3/main/postgresql.conf"]


[/SPOILER]

Das DB-Script muss im Verzeichnis unter db liegen. Den letzten Eintrag für das Anlegen eines Users habe ich daraus entfernt.

Einmalig zum Bauen des Docker Containers

docker build -t eg_postgresql . 

Zum Starten des Docker Containers

docker run -p 5432:5432 eg_postgresql 

Momentan bekomme ich damit bei jedem Start eine leere Datenbank, incl. Schema zur Verfügung gestellt.

Bin aber noch in der Lernphase, wie ich damit effektiv Arbeiten und auch verschiedene DB-Stände managen kann.

Datenbanken verhalten sich trotz JPA oftmals unterschiedlich. Und dann kommt es auch noch stark auf die JPA Implementierung an. Ich würde davon absehen. Wer wirklich an dem Projekt arbeiten möchte, schafft es sicher auch, eine lokale DB aufzusetzen.

edit:

Docker wäre sicherlich eine interessante Option.

MySQL oder PostgreSQL ist mehr oder weniger eine Geschmacksfrage. Ich habe beruflich mit beiden gearbeitet, und habe mit PostgreSQL weniger Probleme gehabt und Überraschungen erlebt. MySQL ist sicher eine gute Datenbank, aber an manchen Stellen brät sie eben immer noch Extrawürste.

@MrEuler : Mit Docker habe ich bis jetzt keine Erfahrungen, und ich bin etwas skeptisch, noch eine neue Technologie ins Spiel zu bringen. Bei komplizierteren Setups sehe ich den Vorteil ja ein, aber ist es in unserem Fall wirklich einfacher, als eine Datenbank zu installieren und ein Script laufen zu lassen? Kommt mir ehrlich gesagt wie Kanonen auf Spatzen vor.

Darauf wollte ich hinaus. Schau, dass es mit MySQL oder PostgreSQL funktioniert und überlass dann die Auswahl einfach dem dev, je nachdem was zur Verfügung steht. Vl. auch schauen, dass es mit sqlite funzt, für wirklich schnelles starten.

Ich hab damit ein wenig rumgespielt und kann den Hype nachvollziehen. Docker vereinfacht nicht nur die Installation, es „verschmutzt“ das System nicht und bietet etwas mehr Sicherheit (wer Kontrolle über einen Docker-Container erhält, hat keinerlei Zugriff auf den Rest des Systems).
Das heißt aber nicht, dass man gezwungen wird, Docker zu nutzen. Wer möchte, kann die Installation selbst vornehmen. Aber wenn zusätzlich ein Docker-File vorhanden ist, wird es gerade für die Endbenutzer richtig einfach.

Als bislang unbeteiligeter wuerde meine Empfehlung zu Maven Profilen hingehen, die je nach Profil verschiedene RDBMS mit JPA nutzen.

Lokal sind H2, Derby, oder HSQL ganz ok, verstehe ehrlich gesagt nicht was das Problem mit H2 war.
So muss keiner extra ein echtes RDBMS verwenden der das nicht will, auschecken und mvn clean verify und los gehts.

Auf einem CI Sever kann dann ein anderes Profil aktiviert sein und Oracle, Postgres, oder sonstwas zum Einsatz kommen.

Docker etc. wuerde ich nicht fuer den Build nehmen, ist schon ein anderes Kaliber, Windows Nutzer gucken in die Roehre, Docker und andere Container sind eher etwas fuers Deployment als fuer den Build.

Docker ist mit Kanonen auf Spatzen geschossen. Dennoch kann dies manchmal Sinn machen. Ein Spatz mit Grippe kann sehr gefährlich werden.

Ich für meinen Teil möchte mich mit Docker beschäftigen, weil ich davon ausgehe, dass ich dieses Wissen früher oder später gut gebrauchen kann.
Zudem denke ich, dass es hier auch eine sinnvolle Einsatzmöglichkeit dafür gibt. Zudem sehe ich das hier auch ein wenig für ein Testfeld im Gegensatz zu RL-Projekten. (Wissenschon)

Die Punkte, die ich für sinnvoll halte sind

Entwicklungs- und Zielumgebung möglichst identisch halten. Auf beiden Systemen das selbe Skript ausgeführt stellt auf beiden Systemen die selbe Umgebung bereit.

Abhängigkeiten der Anwendung werden explizit festgehalten. Momentan ist es die DB, später kommt noch evtl. ein Mailserver für Registrierungen und Benachrichtigungen dazu. Die Installation eines Java-Servers etc. kann man auch integrieren.

Administration/Deployment kann sehr einfach werden. Mit Docker eine Maschine bei Amazon zum laufen zu bringen wird so einfach wie ein Mavenbefehl. Die Rolle die Maven heute für die Entwicklung spielt, wird Docker für die Administration bedeuten.

Deployment gehört meiner Meinung nach zum Entwicklungsprozess dazu.

Dazu kommt noch der Punkt den darekkay erwähnt hat, dass das System sauber bleibt. Wenn ich für andere Projekte eine Inkompatible DB benötige dann muss ich mich entscheiden, welche ich behalte. Ansonsten kann es haarig werden.

Ob Windows Nutzer tatsächlich in die Röhre schauen werde ich noch überprüfen und mich dann melden. Ich gehe aber erstmal davon aus, dass das mit boot2docker ein gangbarer Weg ist.

Hast eigentlich schon mal überlegt ob nicht was anderes als SQL vielleicht sogar besser wäre. Objektdatenbank oder NoSQL Geschichten?

ObjectDB habe ich ja ausprobiert, und es würde auch passen - wenn es für OSS eine kostenlose Version ohne starke Beschränkung gäbe. Bei Sachen wie db4o ist schon die fehlende Administrierbarkeit (nur programmatisch möglich) ein K.O.-Kriterium.

Da eher die Daten und weniger die Beziehungen komplex sind, und sich Entities auch ganz klar definieren lassen, sehe ich hier relativ wenig Nutzen in Graph-, Document- oder Key-Value-DBs.

Vorteile, die bei relationalen Datenbanken gern übersehen werden, sind guter Tool-Support, leichter Zugriff von außen (Datenaustausch, Reporting, Administration) und einfache Migration zwischen Versionen.