使用Hibernate在Spring中使用ReactiveCrudRepository

31

是否有可能使用ReactiveCrudRepository替代CrudRepository与Hibernate和关系型数据库(如Mysql、Postgres等)一起使用?我已经尝试使用Spring Data Jpa和Hibernate进行了一些示例,但是无法完成。我只能找到一些针对MongoDB和cassandraReactiveCrudRepository示例。


欢迎来到StackOverflow。您的问题有些宽泛。请查看帮助页面,特别是如何发布最小完整可验证示例,以便使您的问题更加专注。 - hotzst
4个回答

63
可以使用 R2DBC 和 Postgres、Microsoft SQL Server 或 H2,但不能使用 Hibernate 和 MySQL 代替 CrudRepository 使用 ReactiveCrudRepository。请参考 Spring Data R2DBC

长篇版本

为什么不能使用 JPA?

由于 JPA 基于的思想是将数据模型的一部分加载到内存中,操作生成的对象模型,然后让 JPA 转换这些更改,而且所有这些都在一个事务中完成,因此在可预见的未来不会发生这种情况。

这与处理反应式存储的方式相反,您需要尝试进行原子更改,并尝试解耦加载、处理和存储,而且所有这些都不能阻塞。

为什么不能使用 JDBC?

所以我们需要查看JPA以下的技术水平:JDBC。 但是JDBC仍然是阻塞的:您向数据库发送SQL语句,然后JDBC将阻塞直到您获得结果。 而且这再次违反了反应式的理念:永不阻塞。 可以将其包装在线程池中以在一定程度上缓解此问题,但这更像是一种解决方法而不是解决方案。
为什么需要R2DBC?
对于某些数据库,有一些适合的驱动程序可用于反应式存储库。 但它们是专有的,因此不是真正应该最终适用于所有(相关的)关系型数据库的基础。
Spring Data团队曾经希望ADBA会填补这个空白。 但是邮件列表上的讨论表明,ADBA并不是针对反应式,而只是针对异步。 再次,这不是我们需要的反应式存储库抽象。
因此,在2018年初,生活在反应式和关系交叉点的各种人决定我们需要一种标准的反应式数据库访问方式。

R2DBC (响应式关系型数据库连接) 是这样一项标准的提案。 希望它能够说服 Oracle 转向响应式方法,或者如果无法实现,则成为标准。

而且已经有三种实现可用,第二个选项的机会看起来很有前途。

R2DBC 本身主要是一个 SPI,即数据库提供程序需要实现的 API。 SPI 的设计方式对实现者的要求最少。 但是这也使得 R2DBC 使用起来有些麻烦。 这样做的想法是,其他库将会使用该 SPI 构建出专门用于易用性的库,就像 JDBC 一样。

Spring Data R2DBC

Spring Data R2DBC 是这样一个库,它提供了你所要求的支持:ReactiveCrudRepository,尽管它与 JPA/Hibernate 独立,并且还没有 MySQL 的支持。

项目状态

R2DBC 和 Spring Data R2DBC 都没有发布生产版本,至少需要数月才能完成。

Spring Data R2DBC刚刚发布了第一个里程碑。 请查看发布文章以获取其当前的功能。

R2DBC已经到达第6个里程碑。请参阅发布文章以获取详细信息。

还可以参考这个答案:为什么Spring不提供关系型数据库的反应式(非阻塞)客户端?

原始答案作为考古学家的参考:

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

目前与Spring Data的反应式部分相关的版本是 Spring Data Kay M1 (您可以检查项目主页上是否有更新版本)

Spring Data团队关于该版本的博客文章,特别是其中的反应式部分,开始于(强调我的部分):

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

原因在于没有标准的非阻塞方式来访问关系数据库。因此,目前仅支持支持此类API的数据库。

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


现在一年过去了,有什么新消息吗? :) - dSebastien
1
@dSebastien 不是很确定,但是现在已经有 https://github.com/spring-projects/spring-data-jdbc ,它可能最终会获得反应式支持。同时,也有关于异步数据库访问 API 的活动。你可以在邮件归档中阅读有关讨论的内容:http://mail.openjdk.java.net/mailman/listinfo/jdbc-spec-discuss - Jens Schauder
2
@dSebastien 又过了一年,现在有新消息了。请查看更新后的答案。 - Jens Schauder
3
由于Hibernate有一个响应式版本(https://github.com/hibernate/hibernate-reactive),为什么JPA不支持它?是否会出现类似JPA-Reactive的东西? - The Coder
1
@TheCoder,正如我在答案中所述,JPA和Reactive并不是很匹配。即使JPA规范正在缓慢推进,我也不认为未来几年会出现反应式的JPA。 - Jens Schauder

6
Hibernate启动了一个新的Hibernate Reactive子项目,用于支持反应式流,并提供类似于Hibernate/JPA的API来访问RDBMS。但不幸的是,目前Spring Data还不支持它。因此,没有适用于Hibernate Reactive的ReactiveCrudRepoisoty。
但是,您可以自己将Hibernate与Spring集成,并获得反应式支持。
1.定义persistence.xml文件请注意提供程序类必须指定为Hibernate Reactive中的类。 2.声明Mutiny.SessionFactory bean。 3.然后将其注入到您的存储库类中。
我已经创建了完整的示例演示Hibernate Reactive + Spring。 更新:截至目前,Spring团队没有支持它的计划。如果你想尝试其他框架,请查看Quarkus和Micronaunt,两者都有无缝的Hibernate Reactive支持。请查看我的Quarkus Hibernate Reactive示例Micronaut Hibernate Reactive示例。

你好,一年过去了,Hibernate Reactive对CrudRepository的支持有更新吗? - Krusty the Clown
我知道Spring Data在这方面存在一些问题,请查看#2211#2503,但是Spring团队没有计划添加Hibernate响应式支持。据我所知,目前Quarkus和Micronaut都提供了无缝的Hibernate响应式支持。 - Hantsy

3
根据之前回答中的引用,可以使用JPA或JDBC实现ReactiveCrudRepository,并将工作委托给线程池。这将为外部提供异步API,但仍会消耗线程资源并在独立数据访问之间阻塞,因此只能实现响应式方法的一小部分优点。James Ward声称它可以是非阻塞的。我的意思是我问过他:是不是ScalikeJDBC-Async做的完全一样?只是将查询调用放入另一个线程池?他回答说,不是因为ScalalikeJDBC-Async使用的是实际上是非阻塞(NIO)JDBCish数据库驱动程序的https://github.com/mauricio...。所以你可以通过将Hibernate + Spring Data替换为postgresql-async(应该适用于mysql)来实现响应式。source

0

你可以尝试使用Quarkus框架和Panache Mongo Hibernate响应式存储库。https://quarkus.io/guides/mongodb-panache。它很容易管理MongoDB上的响应式存储库,虽然有点晚但希望能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接