ReactiveCrudRepository 在春季使用 Hibernate

Posted

技术标签:

【中文标题】ReactiveCrudRepository 在春季使用 Hibernate【英文标题】:ReactiveCrudRepository to use Hibernate in spring 【发布时间】:2017-05-19 21:18:17 【问题描述】:

是否可以将 Hibernate 和 RDBMS(mysql、Postgres 等)与 ReactiveCrudRepository 一起使用而不是 CrudRepository?我用 Spring Data Jpa 和 Hibernate 尝试了一些示例,但无法完成。我只能在 ReactiveCrudRepository 上找到一些用于 MongoDB 和 cassandra 的示例。

【问题讨论】:

欢迎来到 ***。你的问题有点宽泛。请查看帮助页面,尤其是有关如何发布您尝试过的minimal complete and verifiable examples 的帮助页面,以便您的问题更加集中。 【参考方案1】:

是否可以将 Hibernate 和 Mysql 与 ReactiveCrudRepository 一起使用而不是 CrudRepository

TL;DR:

不使用 Hibernate 和 MySQL,但使用 R2DBC 和 Postgres、Microsoft SQL Server 或 H2。 看看Spring Data R2DBC。

加长版

为什么不用 JPA?

在包含 Hibernate/JPA 的情况下,这在可预见的将来不会发生。 JPA 基于您将部分数据模型加载到内存中、操作生成的对象模型并让 JPA 转换这些更改的想法。 所有这一切都在一次交易中完成。

这与处理响应式存储的方式完全相反,您尝试进行原子更改并尝试将加载、处理和存储以及所有这一切解耦而不会阻塞。

为什么不用 JDBC?

所以我们要看看JPA下面的技术层次:JDBC。 但是 JDBC 仍然阻塞:您向数据库发送一条 SQL 语句,然后 JDBC 将阻塞,直到您得到结果。 这再次违背了反应式的想法:永远不要阻塞。 可以将其包装在线程池中以在一定程度上缓解这种情况,但这更像是一种变通方法而不是解决方案。

为什么选择 R2DBC?

对于一些可用于反应式存储库的数据库,有一些合适的驱动程序。 但它们是专有的,因此不是真正应该最终适用于所有(相关)关系数据库的东西的良好基础。

一段时间以来,Spring Data 团队希望ADBA 能够填补这一空白。 但是邮件列表上的讨论清楚地表明,ADBA 的目标不是响应式的,而是异步的。 同样不是我们需要的响应式存储库抽象。

因此,在 2018 年初,生活在交叉路口或反应式和关系式的各种人决定我们需要一个反应式数据库访问标准。

R2DBC (Reactive Relational Database Connectivity) 是对这样一个标准的提议。 希望它有助于说服 Oracle 将 ADBA 转移到被动式方法,或者如果这种情况没有发生,它本身就会成为标准。

并且已经有了三个可用的实现,第二个选项看起来很有希望。

R2DBC 本身主要是一个 SPI,即由数据库提供者实现的 API。 SPI 的设计方式对实施者的要求最低。 但这也让 R2DBC 使用起来有些麻烦。 我们的想法是,其他库将在 SPI 的基础上加强并构建专为可用性而设计的库,就像 JDBC 一样。

Spring Data R2DBC

Spring Data R2DBC 就是这样一个库,它提供了您所要求的:支持ReactiveCrudRepository,尽管它独立于 JPA/Hibernate 并且尚不支持 MySQL。

项目状态

R2DBC 和 Spring Data R2DBC 都还没有生产版本,至少需要几个月的时间。

Spring Data R2DBC 刚刚发布了第一个里程碑。 见the release article for its current capabilities。

R2DBC 正处于其第 6 个里程碑。见release article for details。

另请参阅此答案:Why does Spring not provide reactive (non-blocking) clients for relational databases?

原答案供考古学家参考:

截至目前(2017 年 1 月),这是不可能的。

Spring Data 的响应式部分当前相关版本是Spring Data Kay M1(您可以检查是否有更新的版本可用on the project home page)

还有一篇来自 Spring Data 团队的关于该版本的博客文章,特别是其中的反应部分(重点是我的):

Spring Data Kay M1 是第一个支持响应式数据访问的版本。它最初的支持的存储集——MongoDB、Apache Cassandra 和 Redis——都已经提供了响应式驱动程序,这使得它们成为此类原型的非常自然的候选者。

原因是没有标准的非阻塞方式来访问关系数据库。所以现在只支持那些支持这种 API 的。

可以使用 JPA 或 JDBC 实现 ReactiveCrudRepository 并将工作委托给线程池。这将在外部提供异步 API,但仍会消耗线程资源并在独立数据访问之间阻塞,因此只能实现反应式方法的一小部分好处。

【讨论】:

一年过去了有什么消息吗? :) @dSebastien 不是真的,但现在有 github.com/spring-projects/spring-data-jdbc 最终可能会得到被动支持。还有关于异步数据库访问 API 的活动。您可以在邮件档案mail.openjdk.java.net/mailman/listinfo/jdbc-spec-discuss 中阅读有关它的讨论 @dSebastien 一年后有消息。查看更新的答案。 @JensSchauder 既然 Hibernate 有一个响应式版本(github.com/hibernate/hibernate-reactive),为什么 JPA 不支持它?类似 JPA-Reactive 的东西? @TheCoder 正如我在回答 JPA 和 Reactive 中所阐述的那样,它并不真正适合。即使 JPA 规范进展缓慢,我也因此认为未来几年不会出现反应式 JPA。【参考方案2】:

根据上一个答案的引用

可以使用 JPA 或 JDBC 实现 ReactiveCrudRepository,并将工作委托给线程池。这将在外部提供异步 API,但仍会消耗线程资源并在独立数据访问之间阻塞,因此只能实现反应式方法的一小部分好处。

James Ward 声称它可以是非阻塞的。我的意思是我问他:

是的,但是 ScalikeJDBC-Async 不是完全一样吗?只是将查询调用放入另一个线程池?

他回复了

不,因为 ScalalikeJDBC-Async 使用 https://github.com/mauricio... 这实际上是一个非阻塞 (NIO) JDBCish 数据库驱动程序。

source

因此,您可以通过用 postgresql-async 替换 hibernate + spring 数据来做出反应(应该与 mysql 一起使用)。

【讨论】:

【参考方案3】:

您可以尝试使用 quarkus 框架和 panache mongo hibernate 反应式存储库。 https://quarkus.io/guides/mongodb-panache .通过 mongoDB 管理响应式存储库很容易,稍后但希望有所帮助。

【讨论】:

【参考方案4】:

Hibernate 启动了一个新的 Hibernate Reactive 子项目,用于支持响应式流,它提供 Hibernate/JPA 类似的 API 来访问 RDBMS。但不幸的是,目前 Spring Data 并不支持它。所以 Hibernate Reactive 没有 ReactiveCrudRepoisoty

但您可以自己将 Hibernate 与 Spring 集成并获得响应式支持。

    定义一个persistence.xml file,注意提供者类必须指定为Hibernate Reactive中的类。 声明Mutiny.SessionFactory bean。 然后在您的存储库类中inject it。

我创建了a complete example 演示 Hibernate Reactive + Spring。

【讨论】:

以上是关于ReactiveCrudRepository 在春季使用 Hibernate的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot:ReactiveCrudRepository 没有被任何 bean 实现

将 Spring Data 的 ReactiveCrudRepository 应用到 Redis

WebFlux 和 Kotlin 在多模块应用程序中使用 ReactiveCrudRepository

源自Impala 揭秘春晚红旗HS7“跳跳车”

Webflux postgresql

找不到类型 Pairs 的属性 findAll