Idempotenz unter Männern ist ein grosses Problem

Frank war am Boden zerstört. Wie konnte das nur jemals passieren? Er wusste, seine Freundin würde ihn deswegen verlassen. Sie wünschte sich schon immer ein Kind. Doch das Resultat des Doktors ist eindeutig: Frank ist idempotent! Frank weiss nicht, ob er so weiterleben kann, ob er so überhaupt noch ein richtiger Mann ist…

Was bedeutet idempotent?

Scherz beiseite, idempontent ist natürlich ein Begriff aus der Informatik und der Mathematik. In der Mathematik bezeichnet man ein Objekt als idempotent, wenn es mit sich selber verknüpft wieder sich selber ergibt. Warum man das jemals braucht? Da fragen Sie lieber einen Mathematiker.

In der Informatik gilt der Begriff hauptsächlich für Funktionen/Methoden: Eine Funktion ist idempotent, wenn man diese mehrmals hintereinander mit dem gleichen Input aufrufen kann und dabei immer denselben Output erhält.

Das macht in der Informatik mehr Sinn?

Nun, es macht sicherlich mehr Sinn als in der Mathematik. Idempotenz ist etwa eine wichtige Eigenschaft beim Thema Testing. Wenn eine Methode mit dem gleichen Input immer verschiedene Rückgaben gibt, ist diese schlecht für Unit Tests geeignet.

Ein Beispiel?

Ein einfaches Beispiel wäre etwa eine Funktion, die einen Zähler zurückgibt. Jedesmal, wenn ich die Funktion aufrufe (ohne Parameter) kommt ein um 1 höherer Zähler zurück. Diese Funktion ist nicht idempotent.

Eine Funktion, die mir aber immer die Zahl 100 zurückgibt, auch wenn ich sie eine Million Mal aufrufe, ist idempotent.

Was ist JPA?

Enterprise Applikationen führen üblicherweise massenhaft Operationen auf Datenbanken durch, wobei grosse Mengen an Daten bearbeitet werden. Für eine Datenbankanbindung braucht man dabei entweder eine Menge Code, wenn man die Anbindung selber programmiert, oder man verwendet eines der berühmten Frameworks wie Spring. Eine weitere Möglichkeit ist die Verwendung von JPA = Java Persistance API. Dieses Application Programming Interface reduziert den Aufwand, den man hat, um mit einer Datenbank zu kommunizieren.

Die Objekte oder Objektmodelle des Java Programmes werden dabei mit den relationalen Modellen verbunden. Der Unterschied ist dabei, dass die relationalen Objekte der Datenbank eher in tabellenform daherkommt, während das Objekt im Java Code ein Ojekt mit etlichen Attributen darstellt – Wobei jedes Attribut schlussendlich wieder ein ganz anderes Objekt sein kann.

Wie kann mir JPA nun helfen?

JPA ist eine Sammlung von Klassen und Methoden, um das Speichern von Daten in Datenbanken zu unterstützen. Dabei gibt es verschiedene Anbieter von Datenbankdiensten, sogenannte JPA Provider, wie etwa Oracle, Redhat, Eclipse etc. Produkte dieser Firma sind etwa Hibernate, Eclipselink, Toplink oder Spring Data JPA.

Die Idee von JPA ist es, ein ganz normales Java Objekt (POJO, Plain Old Java Object) als relationales Datenbankobjekt zu speichern.

Wie heissen die JPA Objekte?

Das Grundobjekt von JPA ist die sogenannte Entity, welche ein zu persistierendes Objekt darstellt beziehungsweise am Ende einfach ein Record in der Datenbank.

Weitere Objekte sind:

  • Persistence – Beinhaltet statische Methoden, um eine EntityManagerFactory zu erhalten
  • EntityManagerFactory – Erstellt Instanzen von EntityManager
  • EntityManager – Erstellt Istanzen von Query’s
  • EntityTransaction – Jeder EntityManager wird unterstützt von einem EntityTransaction Objekt
  • Query – Wird zur Verfügung gestellt von den JPA Providers, um auf die Daten zuzugreifen

Wie erstellt man eine JPA Entity?

Um diesen Eintrag nicht unnötig aufzublähen, werde ich mich auf die Definition eines Entity Objekts beschränken. Als Beispiel soll ein Buch in einer Buchhandlung als relationales Objekt definiert werden.

Ein Buch kann erstellt, aktualisiert, gefunden und gelöscht werden. Das Buch selber ist dabei ein einfaches POJO, für die vier Transaktionen wird jeweils eine Serviceklasse erstellt:

  • Java Model bzw. POJO: Book.java

Ein Buch ist dabei sehr simpel, es hat gerade mal eine ID und einen Titel. Die Klasse Book.java hat dafür Getter und Setter.
Für die Definition ist die Annotation @Entity zuständig. @Table sagt dabei, welche Tabelle mit dieser Entität erstellt werden soll.

Die Id des Buches wird mit der Annotation @Id versehen – damit wird auch gleich gesagt, dass dies der Primary Key sein soll. Mit der Annotation @GeneratedValue kann man dem System mitteilen, dass ein Wert automatisch generiert werden soll, was hauptsächlich bei Primary Keys Sinn macht (AUTO ist dabei die Standardeinstellung). Diese generierten Werte sind dabei einzigartig für die gesamte Datenbank.

Die Datenbank selber könnte man nun in der Datei Persistence.xml registrieren. Dies lasse ich hier aber aus.

// import javax.persistence.Entity etc.

@Entity
@Table
public class Book {
 
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO) 
   private int id;
   private String title;
 
   public Book(int id, String title) {
     super( );
     this.id = id;
     this.title = title;
   }
 
   // getter und setter und ggf. toString()
}

Entity Beziehungstypen

Zwischen den Entitäten sind verschiedene Beziehungen. Grundsätzlich lässt sich sagen, dass Beziehungen effektiver zwischen Tabellen in der Datenbank sind. JPA behandelt deshalb die Klassen als relationale Tabellen.

Folgende Beziehungen sind möglich:

@ManyToOne
@OneToMany
@OneToOne
@ManyToMany

Die @ManyToOne Beziehung zum Beispiel wäre sinnvoll für die Beziehung zwischen der One Buchhandlung, welche Many Bücher beinhaltet.

Die Beziehung wird nun direkt in der Entität der Klasse Book.java angegeben:

@ManyToOne
private Bookstore bookstore;

Wie spielen die verschiedenen Klassen zusammen?

Ich zeige noch einen konkreten Fall, wie ein Buch erstellt wird. Dabei sieht man schön, wie die oben genannten Klassen zusammenspielen.

Bei dem Beispiel handelt es sich um die Serviceklasse CreateBook.java, welche einem ein Buch erstellt.

// import javax.persistence.Entity etc.

public class CreateBook {
 
 public static void main( String[ ] args ) {
 
    EntityManagerFactory factory = Persistence
    .createEntityManagerFactory( "Eclipselink_JPA" );
 
    EntityManager entityManager = factory.createEntityManager( );
    entityManager.getTransaction( ).begin( );
 
    Book book = new Book( );
    book.setId(1234);
    book.setTitle("Kochen fuer Programmierer");
 
    entityManager.persist( book );
    entityManager.getTransaction( ).commit( );
 
    entityManager.close( );
    factory.close( );
  }
}

So, dies sollte als kurzer Einstieg in das Thema JPA reichen.

Was ist GlusterFS?

GlusterFS ist eine geniale Erfindung, wenn man eine Applikation hat, die auf mehreren Servern läuft und dort Abfragen bearbeitet. GlusterFS ist ein verteiltes Dateisystem, das Speicherelemente von mehreren Servern als einheitliches Dateisystem präsentiert. Mehrere Rechner können dabei gleichzeitig auf ein gemeinsames Dateisystem zugreifen. GlusterFS ist OpenSource und erlaubt die Verschüsselung der Verbindung via Transport Layer Security via OpenSSL.

Stellen Sie sich vor, sie haben 6 Server, auf denen ihre Applikation läuft. Jede ihrer Server verarbeitet Requests und loggt dabei die Erfolgsmeldungen sowie eventuelle Fehler. Wenn Sie nun wissen wollen, ob Ihre Server einen bestimmten Kunden verarbeitet haben – Etwa den Kunden „Kung Fu Panda“ – ist das kein Problem, da sie den Namen der Kunden in den Logfiles speichern. Aber, oh weh, Sie müssen sich jedesmal auf 6 Servern einloggen, um die Logfiles nach dem Kunden zu durchforsten.

Bei diesem Problem kann Ihnen GlusterFS helfen. Die Logfiles können dazu einfach an einem Platz zusammengetragen werden. Dazu kommt, dass Sie sich auf einen beliebigen Server einloggen können, um die Files zu lesen. Bei diesem Beispiel fällt auch auf, dass 6 bereits eine relative hohe Zahl von Server ist und bei GlusterFS beliebig erweitert werden kann, wo bei Alternativen jeweils nur zwei Knoten zu einem Dateisystem verbunden werden konnten.

Dabei gibt es verschiedene Konfigurationsoptionen. Die Dateien können zum Beispiel verteilt gespeichert und dem Client als ein Dateisystem angezeigt werden. Dadurch kann der zur Verfügung stehende Speicher einfach erhöht werden, die Dateien sind dabei aber nicht redundant. Interessanter ist aber wohl in vielen Anwendungsfällen der „Replicated Storage“, bei der jede Datei auf mehreren Servern gespiegelt gespeichert wird. Falls ein Server ausfallen würde, oder eine Daten nicht korrekt abgelegt werden kann, wäre diese immer noch auf dem zweiten Server vorhanden. GlusterFS unterstützt den Administrator dabei, wenn ein sogenannter „Split Brain“ passieren würde: Wenn das Spiegeln (mirroring) einer Datei auseinanderläuft und das File nur noch auf einem der Server im Gluster verfügbar ist.

GlusterFS kann im Netz hier gefunden werden: https://www.gluster.org/

was ist glusterfs replicated.png