将 Hibernate OGM 与云一起使用 MongoDB Atlas M0(免费套餐)
Usage of Hibernate OGM with cloud MongoDB Atlas M0 (Free Tier)
我正在尝试为我的 JAVA EE 应用程序使用 MongoDB Atlas M0(免费套餐),现在我正在使用:
本地MongoDB数据库(v4.0.4)
休眠核心"hibernate-core 5.3.6.Final"
休眠 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 的两个版本,第一个在本地主机上运行良好,第二个是我用来连接到云的版本。
工作本地主机版本:
<?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 云版本:
<?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>
像主机一样,我使用了来自 "standard connection string" 的副本集 URI 来帮助 window 在 Atlas 帐户中,因为 "short SRV connection string" 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-驱动程序版本 3.9.1 而不是内置的 Hibernate 3.6.3,但是两个驱动程序都遇到相同的问题
我的 IP(我的应用程序是从我的笔记本电脑部署的)添加到我的 atlas 帐户 IP 白名单
我可以从 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 抛出这种异常?
可能是 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 文件中,但您可以将其设置在对您的项目更有意义的位置。
编辑:关于错误的补充说明。
I think the problems is that we are not using the factory to create the mongo client。
编辑 2:问题可能是由于不支持 SSL 引起的。
An issue has been created 并包含更多信息
遇到了同样的问题。另外,我启用了 SSL 并且连接成功:
<property name="hibernate.ogm.mongodb.driver.sslEnabled" value="true"/>
我正在尝试为我的 JAVA EE 应用程序使用 MongoDB Atlas M0(免费套餐),现在我正在使用:
本地MongoDB数据库(v4.0.4)
休眠核心"hibernate-core 5.3.6.Final"
休眠 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 的两个版本,第一个在本地主机上运行良好,第二个是我用来连接到云的版本。
工作本地主机版本:
<?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 云版本:
<?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>
像主机一样,我使用了来自 "standard connection string" 的副本集 URI 来帮助 window 在 Atlas 帐户中,因为 "short SRV connection string" 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-驱动程序版本 3.9.1 而不是内置的 Hibernate 3.6.3,但是两个驱动程序都遇到相同的问题
我的 IP(我的应用程序是从我的笔记本电脑部署的)添加到我的 atlas 帐户 IP 白名单
我可以从 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 抛出这种异常?
可能是 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 文件中,但您可以将其设置在对您的项目更有意义的位置。
编辑:关于错误的补充说明。
I think the problems is that we are not using the factory to create the mongo client。
编辑 2:问题可能是由于不支持 SSL 引起的。 An issue has been created 并包含更多信息
遇到了同样的问题。另外,我启用了 SSL 并且连接成功:
<property name="hibernate.ogm.mongodb.driver.sslEnabled" value="true"/>