web-dev-qa-db-ja.com

Spring Webflux + JPA:リアクティブリポジトリはJPAでサポートされていません

アプリを起動するとエラーが発生しますJPA: Reactive Repositories are not supported by JPA. My Pomには以下の依存関係があり、Spring Boot 2.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>

これが私のリポジトリインターフェイスです。

public interface CustomerRepository extends ReactiveCrudRepository {
}

アプリケーションを起動するとエラーがスローされます:

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がサポートされていない場合、誰かがアドバイスしてください、私は何を使うべきですか、どんな助けも感謝します。

12
user10400282

リアクティブ、非同期/非ブロッキングのすべての利点が必要な場合は、スタック全体を非同期/非ブロッキングにする必要があります。実際、JDBCは本質的にブロッキングAPIであるため、JDBCを介してデータベースにアクセスする必要がある場合、完全にリアクティブ/ノンブロッキングアプリを構築することはできません。

ただし、リレーショナルデータベースが必要な場合は、rxjava2-jdbcそして、これはRxJavaとRxJava jdbcの完全な使用例です spring-webflux-async-jdbc-sample

現在、Spring webfluxはMongodb、Redisなどをサポートしているようです。nosqlリアクティブなので、JPAの代わりにspring-boot-starter-data-mongodb-reactive

11
kj007

以前のサポートについては知りませんが、2019年6月9日の時点で、JPAリポジトリでWebFluxを絶対に使用できます!

スタックは完全にリアクティブである必要はありません。 WebFluxは好きですが、リレーショナルデータベースが必要です。

私は持っています:

  • spring-boot-starter-data-redis-reactive
  • spring-boot-starter-webflux
  • spring-boot-starter-data-jpa

編集:(FYI)コードは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: Reactive Repositories are not supported by JPA.は、Spring DataクエリからMono<User>。ただし、Monoラッパーを削除すると、正常に機能するはずです。

src/core/repositories/UserRepository

@Repository
interface UserRepository: CrudRepository<User, Long> {

    fun findUserByUsername(username: String): User?

}
2
Clement

選択したデータベース(H2)はノンブロッキングリアクティブクエリをサポートしていませんが、アップストリームコンポーネントのメリットのために、ブロッキング方式でデータをフェッチし、できるだけ早くリアクティブタイプに変換できます。

JPAリポジトリでメソッドを呼び出すことのブロックの性質については何もできません。ただし、できることは、非反応型を反応型(Flux/Mono)に変換したらすぐに変換することです。これにより、結果を反応的に対処できます。

または、Cassandra、MongoDB、Couchbase、Redisなどのリアクティブモデルをサポートする別のデータベースを使用できます。

0
Yakov Burtsev

この小さなJPAリアクティブラッパーを試すことができます。実際にはリアクティブではありませんが、分離されたThreadPoolでJDBC呼び出しを実行します。

https://github.com/IBM/reactive-components

0
Javier Sainz