Рубрики
Без рубрики

Руководство по гибернации OGM

Изучите основы Hibernate OGM, включая его архитектуру.

Автор оригинала: Kumar Chandrakant.

1. Обзор

В этом уроке мы рассмотрим основы Hibernate Object/Grid Mapper (OGM) .

Hibernate OGM обеспечивает поддержку Java Persistence API (JPA) для хранилищ данных NoSQL. NoSQL-это общий термин, охватывающий широкий спектр хранилищ данных. Например, это включает в себя хранилища данных, ориентированные на ключ, документ, столбцы и графики.

2. Архитектура Hibernate OGM

Hibernate традиционно предлагает механизм объектно-реляционного отображения (ORM) для реляционных баз данных. Hibernate OGM engine расширяет свои функциональные возможности для поддержки хранилищ данных NoSQL. Основным преимуществом его использования является согласованность интерфейса JPA между реляционными и NoSQL хранилищами данных.

Hibernate OGM способен обеспечить абстракцию над несколькими хранилищами данных NoSQL благодаря двум ключевым интерфейсам: DatastoreProvider и GridDialect . Поэтому каждое новое хранилище данных NoSQL, которое оно поддерживает, поставляется с реализацией этих интерфейсов.

На сегодняшний день он поддерживает не все хранилища данных NoSQL, но способен работать со многими из них, такими как Infinispan и Ehcache (ключ-значение), MongoDB и CouchDB (документ) и Neo4j (график).

Он также полностью поддерживает транзакции и может работать со стандартными поставщиками JTA. Во-первых, это может быть обеспечено через контейнер Jakarta EE без какой-либо явной конфигурации. Кроме того, мы можем использовать автономный менеджер транзакций JTA, такой как Narayana, в среде Java SE.

3. Настройка

В этом уроке мы будем использовать Maven для извлечения необходимых зависимостей для работы с Hibernate OGM. Мы также будем использовать MongoDB .

Чтобы уточнить, давайте посмотрим, как настроить их для учебника.

3.1. Зависимости Maven

Давайте рассмотрим зависимости, необходимые для работы с Hibernate OGM и MongoDB:


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


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

Здесь мы извлекаем необходимые зависимости через Maven:

3.2. Единица измерения Стойкости

Нам также придется определить детали хранилища данных в режиме гибернации persistance.xml :


    org.hibernate.ogm.jpa.HibernateOgmPersistence
    
        
        
        
    

Обратите внимание на определения, которые мы предоставили здесь:

  • значение атрибута transaction-type как “JTA” (это означает, что нам нужен менеджер сущностей JTA из EntityManagerFactory)
  • поставщик, который является HibernateOgmPersistence для Hibernate OGM
  • несколько дополнительных сведений, связанных с БД (они обычно различаются в разных источниках данных)

Конфигурация предполагает, что MongoDB запущен и доступен по умолчанию. Если это не так, мы всегда можем предоставить подробную информацию по мере необходимости . Одна из наших предыдущих статей также подробно описывает настройку MongoDB .

4. Определение сущности

Теперь, когда мы прошли через основы, давайте определим некоторые сущности. Если мы раньше работали с Hibernate ORM или JPA, то больше добавить нечего . Это фундаментальная предпосылка гибернации OGM. Это обещает позволить нам работать с различными хранилищами данных NoSQL, просто зная JPA .

В этом уроке мы определим простую объектную модель:

Он определяет классы Article , Author и Editor вместе с их отношениями.

Давайте также определим их в 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...
}

Теперь мы определили классы сущностей и аннотировали их стандартными аннотациями JPA:

  • @Entity чтобы установить их в качестве сущностей JPA
  • @Id для создания первичных ключей для сущностей с UUID
  • @OneToMany и @ManyToOne для установления двунаправленных отношений между сущностями

5. Операции

Теперь, когда мы создали наши сущности, давайте посмотрим, сможем ли мы выполнить с ними некоторые операции. В качестве первого шага нам нужно будет сгенерировать некоторые тестовые данные. Здесь мы создадим Редактор , несколько Автор и некоторые Статьи. Мы также установим их отношения.

После этого, прежде чем мы сможем выполнить какую-либо операцию, нам понадобится экземпляр EntityManagerFactory. Мы можем использовать это для создания EntityManager . Наряду с этим нам нужно создать Менеджер транзакций для обработки границ транзакций.

Давайте посмотрим, как мы можем использовать их для сохранения и извлечения объектов, которые мы создали ранее:

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();
}

Здесь мы используем EntityManager для сохранения корневой сущности, которая каскадируется на все ее отношения. Мы также выполняем эту операцию в пределах определенной границы транзакции.

Теперь мы готовы загрузить объект, который мы только что сохранили, и проверить его содержимое. Мы можем запустить тест, чтобы проверить это:

@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
}

Здесь мы снова используем EntityManager , чтобы найти данные и выполнить стандартные утверждения для них. Когда мы запускаем этот тест, он создает экземпляр хранилища данных, сохраняет сущности, извлекает их обратно и проверяет.

Опять же, мы просто использовали JPA для сохранения сущностей вместе с их отношениями . Аналогично, мы используем JPA для загрузки сущностей обратно , и все это прекрасно работает, даже если наша база данных выбрана MongoDB вместо традиционной реляционной базы данных.

6. Переключение Бэкенда

Мы также можем переключить наш сервер. Давайте теперь выясним, насколько трудно будет это сделать.

Мы изменим наш бэкэнд на Neo4j, который является популярным хранилищем данных, ориентированным на графики .

Во-первых, давайте добавим зависимость Maven для Neo4j :


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

Затем нам нужно будет добавить соответствующую единицу сохранения в ваш persistence.xml :


    org.hibernate.ogm.jpa.HibernateOgmPersistence
    
        
        
        
    

Короче говоря, это самые основные конфигурации, необходимые для Neo4j. Это может быть подробно описано далее по мере необходимости .

Ну, это в значительной степени то, что нужно сделать. Когда мы запускаем тот же тест с Neo4j, что и бэкэнд-хранилище данных, он работает довольно легко.

Обратите внимание, что мы переключили наш сервер с MongoDB, который является хранилищем данных, ориентированным на документы, на Neo4j, которое является хранилищем данных, ориентированным на графики. И мы сделали все это с минимальными изменениями и без необходимости каких-либо изменений в какой-либо из наших операций .

7. Заключение

В этой статье мы рассмотрели основы Hibernate OGM, включая его архитектуру. Впоследствии мы реализовали базовую модель предметной области и выполнили различные операции с использованием различных баз данных.

Как всегда, код для примеров доступен на GitHub .