Ein Leitfaden für den Ruhezustand der OGM

Ein Leitfaden für den Ruhezustand

1. Überblick

In diesem Tutorial werden die Grundlagen vonHibernate Object/Grid Mapper (OGM) erläutert.

Hibernate OGM bietet Unterstützung für Java Persistence API (JPA) für NoSQL-Datenspeicher. NoSQL ist ein Überbegriff für eine Vielzahl von Datenspeichern. Dies umfasst beispielsweise Schlüsselwert-, Dokument-, spalten- und grafikorientierte Datenspeicher.

2. Die Architektur von Hibernate OGM

Hibernate traditionally offers an Object Relational Mapping (ORM) engine für relationale Datenbanken. Hibernate OGM engine extends its functionality to support NoSQL datastores. Der Hauptvorteil der Verwendung ist die Konsistenz der JPA-Schnittstelle über relationale und NoSQL-Datenspeicher hinweg.

Hibernate OGM kann aufgrund von zwei Schlüsselschnittstellen,DatastoreProvider undGridDialect, eine Abstraktion über eine Reihe von NoSQL-Datenspeichern bereitstellen. Daher wird jeder neue unterstützte NoSQL-Datenspeicher mit einer Implementierung dieser Schnittstellen geliefert.

Bis heute werden nicht alle NoSQL-Datenspeicher unterstützt, aber es kann mit vielen von ihnen wie Infinispan und Ehcache (Schlüsselwert), MongoDB und CouchDB (Dokument) und Neo4j (Grafik) zusammenarbeiten.

It also fully supports transactions and can work with standard JTA providers. Erstens kann dies ohne explizite Konfiguration über den Java EE-Container bereitgestellt werden. Darüber hinaus können wir einen eigenständigen JTA-Transaktionsmanager wie Narayana in der Java SE-Umgebung verwenden.

3. Konfiguration

In diesem Lernprogramm verwenden wir Maven, um die erforderlichen Abhängigkeiten für die Arbeit mit Hibernate OGM abzurufen. Wir werden auchMongoDB verwenden.

Schauen wir uns zur Verdeutlichung an, wie Sie sie für das Lernprogramm einrichten.

3.1. Maven-Abhängigkeiten

Sehen wir uns die Abhängigkeiten an, die für die Arbeit mit Hibernate OGM und MongoDB erforderlich sind:


    org.hibernate.ogm
    hibernate-ogm-mongodb
    5.4.0.Final


    org.jboss.narayana.jta
    narayana-jta
    5.9.2.Final

Hier ziehen wir die erforderlichen Abhängigkeiten durch Maven:

3.2. Persistenz-Einheit

Wir müssen auchdefine datastore details im Ruhezustandpersistance.xml:


    org.hibernate.ogm.jpa.HibernateOgmPersistence
    
        
        
        
    

Beachten Sie die Definitionen, die wir hier bereitgestellt haben:

  • Der Wert des Attributtransaktionstyps als "JTA" (dies impliziert, dass wir einen JTA-Entitätsmanager ausEntityManagerFactory) wünschen

  • der Anbieter, derHibernateOgmPersistence für Hibernate OGM ist

  • Einige zusätzliche Details zur Datenbank (diese variieren normalerweise zwischen verschiedenen Datenquellen)

Die Konfiguration setzt voraus, dass MongoDB ausgeführt wird und standardmäßig verfügbar ist. Ist dies nicht der Fall, können wir immerprovide details as necessary. Einer unserer vorherigen Artikel behandelt auchsetting up MongoDB in detail.

4. Entitätsdefinition

Nachdem wir die Grundlagen durchgearbeitet haben, definieren wir einige Entitäten. If we worked with Hibernate ORM or JPA before, this has nothing more to add. Dies ist die Grundvoraussetzung von Hibernate OGM. Espromises to let us work with different NoSQL datastores with just the knowledge of JPA.

In diesem Tutorial definieren wir ein einfaches Objektmodell:

image

Es definiert die KlassenArticle,Author undEditor zusammen mit ihren Beziehungen.

Definieren wir sie auch in Java:

@Entity
public class Article {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String articleId;

    private String articleTitle;

    @ManyToOne
    private Author author;

    // constructors, getters and setters...
}
@Entity
public class Author {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String authorId;

    private String authorName;

    @ManyToOne
    private Editor editor;

    @OneToMany(mappedBy = "author", cascade = CascadeType.PERSIST)
    private Set
authoredArticles = new HashSet<>(); // constructors, getters and setters... }
@Entity
public class Editor {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    private String editorId;

    private String editorName;
    @OneToMany(mappedBy = "editor", cascade = CascadeType.PERSIST)
    private Set assignedAuthors = new HashSet<>();

    // constructors, getters and setters...
}

Wir haben jetzt Entitätsklassen definiert und sie mit JPA-Standardanmerkungen versehen:

  • @Entity, um sie als JPA-Einheiten zu etablieren

  • @Id, um Primärschlüssel für die Entitäten mit UUIDs zu generieren

  • @OneToMany und@ManyToOne, um bidirektionale Beziehungen zwischen den Entitäten herzustellen

5. Operationen

Nachdem wir unsere Entitäten erstellt haben, wollen wir sehen, ob wir einige Operationen an ihnen ausführen können. In einem ersten Schritt müssen wir einige Testdaten generieren. Hier erstellen wirEditor, einigeAuthor und einigeArticle.. Außerdem stellen wir ihre Beziehungen her.

Bevor wir eine Operation ausführen können, benötigen wir eine Instanz vonEntityManagerFactory.. Damit können wirEntityManager erstellen. Zusammen mit diesem müssen wirTransactionManager erstellen, um Transaktionsgrenzen zu behandeln.

Lassen Sie uns sehen, wie wir diese verwenden können, um die zuvor erstellten Entitäten beizubehalten und abzurufen:

private void persistTestData(EntityManagerFactory entityManagerFactory, Editor editor)
  throws Exception {
    TransactionManager transactionManager =
      com.arjuna.ats.jta.TransactionManager.transactionManager();
    transactionManager.begin();
    EntityManager entityManager = entityManagerFactory.createEntityManager();

    entityManager.persist(editor);
    entityManager.close();
    transactionManager.commit();
}

Hier verwenden wirEntityManager, um die Stammentität beizubehalten, die zu all ihren Beziehungen kaskadiert. Wir führen diese Operation auch innerhalb einer definierten Transaktionsgrenze durch.

Jetzt können wir die Entität laden, die wir gerade beibehalten haben, und ihren Inhalt überprüfen. Wir können einen Test durchführen, um dies zu überprüfen:

@Test
public void givenMongoDB_WhenEntitiesCreated_thenCanBeRetrieved() throws Exception {
    EntityManagerFactory entityManagerFactory =
      Persistence.createEntityManagerFactory("ogm-mongodb");
    Editor editor = generateTestData();
    persistTestData(entityManagerFactory, editor);

    TransactionManager transactionManager =
      com.arjuna.ats.jta.TransactionManager.transactionManager();
    transactionManager.begin();
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    Editor loadedEditor = entityManager.find(Editor.class, editor.getEditorId());

    assertThat(loadedEditor).isNotNull();
    // Other assertions to verify the entities and relations
}

Hier verwenden wir erneut dieEntityManager, um die Daten zu finden und Standardzusicherungen durchzuführen. Wenn wir diesen Test ausführen, instanziiert er den Datenspeicher, behält die Entitäten bei, ruft sie zurück und überprüft sie.

Wir haben wiederjust used JPA to persist the entities along with their relationship. In ähnlicher Weise funktioniertwe use JPA to load the entities back und alles funktioniert einwandfrei, selbst wenn unsere Datenbankauswahl MongoDB anstelle einer herkömmlichen relationalen Datenbank ist.

6. Backend wechseln

Wir können auch unser Backend wechseln. Lassen Sie uns jetzt herausfinden, wie schwierig es sein wird, dies zu tun.

Fügen wir zunächst dieMaven dependency for Neo4j hinzu:


    org.hibernate.ogm
    hibernate-ogm-neo4j
    5.4.0.Final

Als nächstes müssen wir die relevante Persistenzeinheit in unserepersistence.xml einfügen:


    org.hibernate.ogm.jpa.HibernateOgmPersistence
    
        
        
        
    

Kurz gesagt, dies sind die grundlegenden Konfigurationen, die für Neo4j erforderlich sind. Dies kanndetailed further as required sein.

Genau das muss getan werden. Wenn wir mit Neo4j den gleichen Test wie mit dem Backend-Datenspeicher ausführen, funktioniert er ziemlich nahtlos.

Beachten Sie, dass wir unser Backend von MongoDB, einem dokumentenorientierten Datenspeicher, auf Neo4j, einen graphorientierten Datenspeicher, umgestellt haben. And we did all this with minimal changes and without needing any changes in any of our operations.

7. Fazit

In diesem Artikel haben wir die Grundlagen von Hibernate OGM einschließlich seiner Architektur erläutert. Anschließend haben wir ein grundlegendes Domänenmodell implementiert und verschiedene Operationen mit verschiedenen DBs ausgeführt.

Wie immer ist der Code für die Beispieleover on GitHub verfügbar.