Spring boot Spring Webflux+;JPA:JPA不支持反应式存储库
启动我的应用程序时出错Spring boot Spring Webflux+;JPA:JPA不支持反应式存储库,spring-boot,spring-data-jpa,spring-webflux,Spring Boot,Spring Data Jpa,Spring Webflux,启动我的应用程序时出错JPA:JPA不支持反应式存储库。 我的Pom有以下依赖项,我使用的是SpringBoot2.0.5 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency&
JPA:JPA不支持反应式存储库。
我的Pom有以下依赖项,我使用的是SpringBoot2.0.5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
当我启动应用程序时,它会抛出错误:
org.springframework.dao.InvalidDataAccessApiUsageException: Reactive Repositories are not supported by JPA. Offending repository is com.example.demo.CustomerRepository!
at org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport.useRepositoryConfiguration(RepositoryConfigurationExtensionSupport.java:310) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport.getRepositoryConfigurations(RepositoryConfigurationExtensionSupport.java:103) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn(RepositoryConfigurationDelegate.java:126) ~[spring-data-commons-2.0.10.RELEASE.jar:2.0.10.RELEASE]
at org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport.registerBeanDefinitions(AbstractRepositoryConfigurationSourceSupport.java:60) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromRegistrars$1(ConfigurationClassBeanDefinitionReader.java:358) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_144]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:357) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:145) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:328) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:233) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:271) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:91) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:61) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
如果JPA不受支持,请告诉我应该使用什么,非常感谢您的帮助。如果您想获得反应式异步/非阻塞的所有好处,您需要使整个堆栈异步/非阻塞。JDBC本质上确实是一个阻塞API,因此如果需要通过JDBC访问数据库,则无法构建完全反应/非阻塞的应用程序 但您仍然需要关系数据库,然后建议使用
rxjava2jdbc
,下面是使用RxJava和rxjavajdbc的完整示例
似乎目前SpringWebFlux支持Mongodb、Redis等nosql反应式,因此使用
SpringBootStarter数据Mongodb反应式您可以尝试这个小型JPA反应式包装器,它不是真正的反应式包装器,而是在一个孤立的线程池上运行JDBC调用
即使您选择的数据库(H2)不支持非阻塞反应式查询,您仍然可以以阻塞方式获取数据,然后尽快将其转换为反应式类型,以利于上游组件
对于在JPA存储库上调用方法的阻塞性质,您无能为力。但是,您可以做的是,在收到非反应性类型后,立即将其转换为反应性类型(通量/单声道),以便从那时起可以反应性地处理结果
或者您可以使用另一个支持反应式模型的数据库,如Cassandra、MongoDB、Couchbase或Redis。我不知道以前的支持情况,但从2019年6月9日起,您完全可以将WebFlux与JPA存储库一起使用
您的堆栈不必是完全反应的。我喜欢WebFlux,但需要一个关系数据库
我有:
- 弹簧启动启动器数据redis reactive
- 弹簧启动器webflux
- spring引导启动器数据jpa
编辑:(仅供参考)代码在Kotlin中,但仍应在Java中工作
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = ["com.example.core.repositories"])
@EnableJpaAuditing
class PersistenceConfig
src/core/models/User
@Entity
@Table(name = "user")
class User(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
var id: Long,
@Column(name = "username")
var username: String,
@Column(name = "created_date", nullable = false, updatable = false)
@CreatedDate
@Temporal(TemporalType.TIMESTAMP)
val createdDate: Date,
@Column(name = "modified_date")
@LastModifiedDate
@Temporal(TemporalType.TIMESTAMP)
val modifiedDate: Date
) : Serializable {
/**
* This constructor is not to be used. This is for hibernate,
* which requires an empty constructor.
*/
constructor() : this(1L, "", "", Date(), Date())
companion object {
private const val serialVersionUID = 2398467923L
}
}
我得到了相同的JPA:JPA不支持反应式存储库。
当我仍然从Spring数据查询返回mono对象时出错,如mono
。但是,如果删除Mono
包装器,它应该可以正常工作
src/core/repositories/UserRepository
@Repository
interface UserRepository: CrudRepository<User, Long> {
fun findUserByUsername(username: String): User?
}
@存储库
接口用户存储库:CrudRepository{
fun findUserByUsername(用户名:字符串):用户?
}
为什么不使用R2DBC?它支持对关系数据库存储的反应式访问,并支持Postgresql、SQL server等
回答得好。然而,如果你的意思是这样的话,这个例子就没有用了。它只是将crudepository
包装在Flux
和Mono
s中。Spring Data Redis不支持反应式存储库:@kj007您能解释一下“阻塞API”是什么意思吗?JDBC查询返回一个ResultSet
和一个调用可以很快返回的AFAIK——它不需要实际获取整个结果集,尽管这是许多数据库的默认行为。我相信MySQL和PostgreSQL都有将结果集一次传输几个记录的方法,而不是一次传输所有记录。@Frans尽管速度很快,但在等待响应时仍然会阻塞线程。反应式是基于消息传递/回调的,因此您可以发出数据库请求,关闭线程,回调将在另一个线程中处理。比什么都不做更好的是,hope将有一个标准的jpa反应式。。。没过几年我就知道了。。。需要等待eclipseLocks,这是一个非常有前途的实现。似乎Hibernate团队正在做一些事情,如果最终在这里使用它,您将失去事务支持和更多。您的会话仅在调用findUserByUsername时才处于活动状态—不再是。所以不支持延迟加载关系等。它不支持manytone-,OnetoMany-,。。。关系
@Repository
interface UserRepository: CrudRepository<User, Long> {
fun findUserByUsername(username: String): User?
}