Использование Hibernate OGM с облаком MongoDB Atlas M0 (Free Tier) - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь использовать MongoDB Atlas M0 (Free Tier) для моего приложения JAVA EE, сейчас я использую:

  • Локальная база данных MongoDB (v4.0.4)

  • Hibernate Core "hibernate-core 5.3.6.Final"

  • Hibernate OGM "hibernate-ogm-mongodb 5.3.1.Final"

  • Сервер приложений Java WildFly 15.0.0.Final.

С локальной базой данных пары MongoDB и Hibernate OGM работают как чудо, но когда я пыталсяподключить Hibernate с Mongo Atlas на свободном уровне для тестирования облачной базы данных, я не смог установить работающее соединение, потому что драйвер mongodb выдает исключение com.mongodb.MongoSocketReadException: преждевременно достигнут конец потока

Я предоставлю две версии моего файла persistence.xml, первая отлично работает с localhost, а вторая - то, что я использовал для подключения к облаку.

рабочая версия localhost:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">

    <!--   @@@   MongoDB   HIBERNATE   OGM   PERSISTENCE   UNIT   @@@   -->
    <persistence-unit name="PersistenceUnitNoSQL" transaction-type="JTA">

        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>

        <class>org.companyname.model.UserEntity</class>
        <class>org.companyname.model.ItemEntity</class>

        <properties>

            <property name="hibernate.ogm.datastore.provider" value="mongodb"/>
            <property name="hibernate.ogm.datastore.host" value="localhost:27017"/>
            <property name="hibernate.ogm.datastore.database" value="databasename"/>
            <property name="hibernate.ogm.datastore.create_database" value="true"/>

        </properties>

    </persistence-unit>

</persistence>

не работает Atlas Cloud версия:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">

    <!--   @@@   MongoDB   HIBERNATE   OGM   PERSISTENCE   UNIT   @@@   -->
    <persistence-unit name="PersistenceUnitNoSQL" transaction-type="JTA">

        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>

        <class>org.companyname.model.UserEntity</class>
        <class>org.companyname.model.ItemEntity</class>

        <properties>

            <property name="hibernate.ogm.datastore.provider" value="mongodb"/>
            <property name="hibernate.ogm.datastore.host" value="cluster0-clustername-shard-00-00-raa4n.mongodb.net:27017,cluster0-clustername-shard-00-01-raa4n.mongodb.net:27017,cluster0-clustername-shard-00-02-raa4n.mongodb.net:27017"/>

            <property name="hibernate.ogm.datastore.database" value="databasename"/>
            <property name="hibernate.ogm.datastore.create_database" value="true"/>

        <property name="hibernate.ogm.datastore.username" value="atlas-user-name"/>
        <property name="hibernate.ogm.datastore.password" value="atlas-user-password"/>
        <property name="hibernate.ogm.mongodb.authentication_mechanism" value="SCRAM_SHA_1"/>

        </properties>

    </persistence-unit>

</persistence>

Подобно узлу, который я использовал, реплика устанавливает URI из «стандартной строки подключения» из окна помощи в учетной записи Atlas, поскольку при «короткой строке подключения SRV» Hibernate генерирует org.hibernate.service.spi.ServiceException: OGM000072: Невозможно настроить провайдера хранилища данных , поэтому я думаю, что этот тип соединения пока не поддерживается.

Так что с этой последней конфигурацией persistence.xml у меня была следующая ошибка:

20:02:01,094 INFO  [org.mongodb.driver.cluster] (ServerService Thread Pool -- 78) Cluster description not yet available. Waiting for 30000 ms before timing out
20:02:01,175 INFO  [org.mongodb.driver.cluster] (cluster-ClusterId{value='5c5497a97aea6111622c7540', description='null'}-cluster0-clustername-shard-00-02-raa4n.mongodb.net:27017)
Exception in monitor thread while connecting to server cluster0-clustername-shard-00-02-raa4n.mongodb.net:27017: com.mongodb.MongoSocketReadException: Prematurely reached end of stream
    at com.mongodb.internal.connection.SocketStream.read(SocketStream.java:112)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:570)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:441)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:295)
    at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:255)
    at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83)
    at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:33)
    at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:106)
    at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:63)
    at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:127)
    at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117)
    at java.lang.Thread.run(Thread.java:748)

Hibernate пытается соединиться с каждым осколком (00-00, 00-01, 00-02), но со всеми исключениями выдает это исключение.

Что я пытался сделать, чтобы решить проблему:

  • с использованием mongo-java-driver версии 3.9.1 вместо встроенного в Hibernate 3.6.3, но оба драйвера работают с одной и той же проблемой

  • мой IP добавлен (мое приложение развернуто с моего ноутбука) в белый список IP-адресов моей учетной записи atlas

  • Я могу нормально подключиться к кластеру из Mongo Shell и MongoDB Compass

  • У меня были сомненияо "hibernate.ogm.mongodb.authentication_mechanism", но "SCRAM_SHA_1" и "BEST" у меня не сработали

  • и, наконец, я попытался установить соединение с кластером из Javaнапрямую (без Hibernate)

с

MongoClient mongoClient = MongoClients.create("mongodb+srv://atlas-user-name:atlas-user-password@cluster0-clustername-raa4n.mongodb.net/test?retryWrites=true");

или

MongoClient mongoClient = MongoClients.create("mongodb://atlas-user-name:atlas-user-password@cluster0-clustername-shard-00-00-raa4n.mongodb.net:27017,cluster0-clustername-shard-00-01-raa4n.mongodb.net:27017,cluster0-clustername-shard-00-02-raa4n.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-clustername-shard-0&authSource=admin&retryWrites=true");

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

Так что моя проблема в том, почему Hibernate выбрасывает такого рода исключения?

1 Ответ

0 голосов
/ 05 февраля 2019

Возможно, что-то не так в том, как Hibernate OGM создает клиента.

Я думаю, что самый простой способ проверить это сейчас - переопределить MongoDBDatastoreProvider и предоставить инициализированный MongoClient.

Это можно сделать, расширив MongoDBDatastoreProvider и переопределив метод createMongoClient.Что-то вроде:

package org.myprojects;

import org.hibernate.ogm.datastore.mongodb.impl.MongoDBDatastoreProvider;

public class MYCustomMongoDBDatastoreProvider extends MongoDBDatastoreProvider {

    @Override
    protected MongoClient createMongoClient(MongoDBConfiguration config) {    
       return MongoClients.create(...);
    }

}

, затем используйте свойство OgmProperties.DATASTORE_PROVIDER для использования вашего провайдера хранилища данных:

hibernate.ogm.datastore.provider = org.myprojects.MYCustomMongoDBDatastoreProvider

В этом примере я устанавливаю его в файле hibernate.properties, но выможет установить его там, где это имеет больше смысла для вашего проекта.

РЕДАКТИРОВАТЬ : дополнительные пояснения по поводу ошибки.

Я думаю, что проблема заключается в том, что мы неиспользуя фабрику для создания клиента монго .

РЕДАКТИРОВАТЬ 2 : Проблема может быть вызвана отсутствием поддержки SSL. Была создана проблема и содержит дополнительную информацию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...