OrientDB – NoSQL in Java

OrientDB ist eine in Java geschriebene Open Source NoSQL Datenbank. Sie kann in Memory, als Server, im Cluster oder auch embedded in Java Anwendungen betrieben werden. OrientDB unterstützt das Document und das Graph Data Model. On top auf das Document Model bietet OrientDB auch die Möglichkeit direkt Java Objekte zu speichern. Auf die Verwendung als Object-Database, embedded in einer Java Anwendung will ich in diesem Artikel näher eingehen.

Theorie

Die Verwendung von OrientDB in einer Java Anwendung (als Object-Database) ist denkbar einfach. Java-Objekte können mit einem einzelnen Befehl einfach gespeichert bzw. gelesen werden. Man muss sich nicht um die De- / Serialisierung kümmern. Es muss auch kein Schema angegeben werden, dadurch können einmal gespeicherte Objekte auch dann wieder gelesen werden, wenn sich die Attribute der Klasse geändert haben. Attribute, die zuvor gespeichert wurden, aber beim Lesen in der Klasse nicht mehr existieren, werden ignoriert. Das Handling ist wesentlich einfacher als mit JPA und relationalen Datenbanken.

Trotzdem können alt bekannte Features aus relationalen Datenbanken genutzt werden. ACID Transactions sind genau so möglich wie ganz normale SQL Abfragen. Das macht den Umstieg besonders einfach.

Wer sich also nicht mit Relationen rumschlagen will, einfach Dokumente bzw. Java-Objekte speichern möchte, dabei aber nicht auf eine stabile, robuste und schnelle Datenbank mit Abfrage-Möglichkeiten verzichten will, für den ist OrientDB genau das richtige. Gegenüber CouchDB oder MongoDB hat es zudem den Vorteil, dass es in Java ist und ganz einfach embedded genutzt werden kann, ohne dass man eine weitere Runtime bzw. eine extra installierte Datenbank benötigt. OrientDB lässt sich als jar-Files ganz einfach mit der eigenen Anwendung ausliefern und direkt aus Java über Java APIs ansprechen. Als Server betrieben bietet OrientDB zudem eine REST Schnittstelle.

Praxis

Genug Theorie, jetzt zur Praxis und der Verwendung von OrientDB embedded in einer Java Anwendung.

Installation

Um OrientDB zu „installieren“ einfach die Distribution herunter laden, ich habe Version 1.3.0 verwendet, und entpacken. Im Classpath der eigenen Anwendung benötigt man folgende JAR-Files (* steht für die Versionsnummer):

  • javassist-*.jar
  • orient-commons-*.jar
  • orientdb-core-*.jar
  • orientdb-object-*.jar

Das war es schon mit der „Installation“.

Datenbank mit POJOs nutzen

Um die Datenbank zu nutzen, muss man sie öffnen bzw. anlegen, wenn sie noch nicht existiert.

// Datenbank Instanz erzeugen
OObjectDatabaseTx db = new OObjectDatabaseTx("local:d:/databases/orient");

// wenn sie nicht existiert anlegen, sonst öffnen
if (!db.exists()) {
  db.create();
} else {
  db.open("admin", "admin");
}

// Entitäten registrieren
db.getEntityManager()
  .registerEntityClasses("de.discoveration.rechnung.dao.orbit.model");

// etwas mit der DB machen ...

db.close();

Beim Datenbank Instanz erzeugen wird eine spezielles ObjectDatabase-DB-Objekt verwendet um mit POJOs arbeiten zu können und eine URL auf die DB angegeben. Hier verwende ich eine lokale URL auf das lokale Filesystem.
Um mit POJOs arbeiten zu können, müssen diese registriert werden. Beim Registrieren der Entitäten gebe ich ein Pakage an, alle Klassen in diesem Pakage werden automatisch registriert und können damit von der DB gespeichert und gelesen werden. Alternativ können auch direkt Java-Klassen angegeben werden.

POJO speichern

Registrierte POJOs können einfach über die save-Methode gespeichert werden.

OObjectDatabaseTx db = new OObjectDatabaseTx("local:d:/databases/orient");
db.getEntityManager().registerEntityClasses("de.discoveration.rechnung.dao.orbit.model");

Todo todo = new Todo();
todo.setSummary("Test");
todo.setDescription("Test am " + new Date());
todo = db.save(todo);

db.close();

OrientDB arbeitet mit Proxys, von daher ist es wichtig sich das gespeicherte Objekt wieder geben zu lassen, wenn man im weiteren Programmcode damit arbeiten möchte. Ansonsten werden weitere Änderungen nicht in der DB reflektiert.

POJO lesen

Um POJOs von der DB zu lesen kann man zum einen mit der API Objekte abfragen oder eine SQL-Query absetzen.

Alle Einträge einer Klasse ermitteln:

OObjectDatabaseTx db = new OObjectDatabaseTx("local:d:/databases/orient");
db.getEntityManager().registerEntityClasses("de.discoveration.rechnung.dao.orbit.model");

// Alle Objekte vom Typ Todo lesen und ausgeben
for (Todo todo : db.browseClass(Todo.class)) {
  System.out.println(todo);
}

db.close();

Abfrage über SQL-Query:

OObjectDatabaseTx db = new OObjectDatabaseTx("local:d:/databases/orient");
db.getEntityManager().registerEntityClasses("de.discoveration.rechnung.dao.orbit.model");

// Alle Todo lesen und ausgeben deren Summary mit Test anfängt
List result = db.query(new OSQLSynchQuery(
  "select * from todo where summary like 'Test%'"));

for (Todo todo : result) {
  System.out.println(todo);
}

db.close();

POJO in DB ändern

Um einen Eintrag in der DB zu ändern muss dieser lediglich gelesen, geändert und dann wieder gespeichert werden. Wichtig dabei ist, den Proxy zu verwenden.

OObjectDatabaseTx db = new OObjectDatabaseTx("local:d:/databases/orient");
db.getEntityManager().registerEntityClasses("de.discoveration.rechnung.dao.orbit.model");

// Alle Todo deren Summary mit Test anfängt auf erledigt setzen
List result = db.query(new OSQLSynchQuery(
  "select * from todo where summary like 'Test%'"));

for (Todo todo : result) {
  Done done = new Done();
  done.setName("Marco");
  done.setComment("fixed");
  todo.setDone(done);
  db.save(todo);
}

db.close();

POJO in der DB löschen

Um Einträge in der DB zu löschen wird die delete-Methode verwendet. Auch hier ist darauf zu achten, dass mit dem Proxy gearbeitet wird.

OObjectDatabaseTx db = new OObjectDatabaseTx("local:d:/databases/orient");
db.getEntityManager().registerEntityClasses("de.discoveration.rechnung.dao.orbit.model");

// Alle Todo deren Summary mit Test anfängt löschen
List result = db.query(new OSQLSynchQuery(
  "select * from todo where summary like 'Test%'"));

for (Todo todo : result) {
  db.delete(todo);
}

db.close();

Hinweise

Getter / Setter verwenden

Da OrientDB mit Proxys arbeitet, ist es wichtig, dass immer die Getter und Setter der Java Objekte verwendet werden und niemals die Attribute direkt. Auch innerhalb einer Klasse, z.B. in der toString-Methode ist das wichtig.

@Override
public String toString() {
  String str = "Todo [summary=" + getSummary() + ", description="
    + getDescription() + ", done=" + getDone() + "]";
  return str;
}

Ich hatte zunächst die Attribute direkt verwendet und in der Ausgabe immer null als Wert bekommen. Ich war schon ganz verzweifelt und hatte mich gewundert, warum OrientDB die Werte nicht speichert. Aber nach dem ich die Getter verwendet hatte, wurden diese angezeigt.

ConnectionPool

In einer richtigen Anwendung ist es besser den ConnectionPool zu verwenden und nicht bei jedem Zugriff eine Verbindung zur Datenbank zu öffnen und wieder zu schließen.

// OPEN THE DATABASE
OObjectDatabaseTx db= OObjectDatabasePool.global().acquire("remote:localhost/petshop", "admin", "admin");

weiterführende Links

Sample

Im Anhang habe ich ein kleines Sample-Programm, das die Beispiele zeigt.

Sample Code OrbitDB

3 Replies to “OrientDB – NoSQL in Java”

  1. Nun ich sehe das mit der etwas größeren Brille. Ich finde das prinzipiell cool, wie aber adressiert man da Themen die momentan im Information Management Segment hype sind. Würden wir beispielsweise ein DWH auf solch einer Basis bauen? Wie nutzen wir eine solche Datenbank im Kontext Analytics, die Standard Tools basieren auf anderen Strukturen. Mir fehlts da noch an Ideen, oder auch an Benchmarks die zeigen das solche Lösungen dort tauglich bzw die gespeicherten Daten auch dort nutzbar sind.

    • Die Tatsache, dass die Big Player Google und Facebook keine relationalen sondern NoSQL Datenbanken nutzen, wirft auf die Frage schon ein interessantes Bild. Google nutzt Big Table, Facebook Cassandra. Machen die beiden Analytics? Ich denke schon, immerhin leben die von der Auswertung der Daten die sie haben. Nutzen sie für Analytics genau diese DBs? Wäre mal interessant das zu recherchieren. Ist OrientDB auch für das „große Spiel“ geeignet? Spannende Frage, Daniel hat sich vorgenommen dazu mal ein paar Tests zu machen.
      Hier noch ein interessanter Vergleich von NoSQL DBs.

  2. Ganz klar, Google und Konsorten machen das so, richtig und Analytics machen die auch. Nur Google und Konsorten machen das
    – selber, mit eigenen Algos etc..
    – gibts noch keine 20 Jahre und haben demzufolge keine Altlasten
    – Die Kaufwerkzeuge sind auf relationale DBs abgestimmt bzw den sogenannten strukturierten Daten.

    Nun habe ich keine Ahnung wie genau die nonSQL DBs ihr Zeug abspeichern und wie gut man dasin verwertbare Strukturen bekommt. Klar worst case muss man die Daten als unstrukturiert behandeln und strukturieren. Das geht Werkzeuge gibts, aber der Aufwand ist erstmal nicht vertretbar, zumindest bekommt man das nicht bei einem Fachbereich bezahlt.
    Schwieriges Unterfangen ist das, vielleicht muss man eben alles auch nach dem Prinzip „Schuster bleib in deinen Leisten“ behandeln, also hoch volatile Daten in non SQL und persistente in SQL DBs ablegen. Sowas könnte dann asynchron ablaufen. Nun den Kommentar auf das hebe ich mir aber für später auf…Ätsch.

Schreibe einen Kommentar

Anmelden um einen Kommentar abzugeben.

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*