spring-data-commons-2.0.0: 未找到 属性 类型 T 的删除! ReactiveCrudRepository

spring-data-commons-2.0.0: No property delete found for type T! ReactiveCrudRepository

问题通过扩展 ReactiveCrudRepository 尝试 spring web 反应以及 spring 数据。我收到以下错误

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property delete found for type Product!
        at org.springframework.data.mapping.PropertyPath.lambda$new[=12=](PropertyPath.java:82) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at java.util.Optional.orElseThrow(Optional.java:290) ~[na:1.8.0_101]
        at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:82) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:304) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:284) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:211) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.repository.query.parser.Part.<init>(Part.java:81) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.repository.query.parser.PartTree$OrPart.lambda$new[=12=](PartTree.java:239) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:193) ~[na:1.8.0_101]
        at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:175) ~[na:1.8.0_101]
        at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_101]
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_101]
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_101]
        at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:240) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.repository.query.parser.PartTree$Predicate.lambda$new[=12=](PartTree.java:368) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:193) ~[na:1.8.0_101]
        at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_101]
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_101]
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_101]
        at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:369) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:92) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:67) ~[spring-data-jpa-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:103) ~[spring-data-jpa-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:214) ~[spring-data-jpa-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:77) ~[spring-data-jpa-2.0.0.BUILD-SNAPSHOT.jar:na]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$null[=12=](RepositoryFactorySupport.java:410) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:193) ~[na:1.8.0_101]
        at java.util.Iterator.forEachRemaining(Iterator.java:116) ~[na:1.8.0_101]
        at java.util.Collections$UnmodifiableCollection.forEachRemaining(Collections.java:1049) ~[na:1.8.0_101]
        at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_101]
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_101]
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_101]
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_101]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$new(RepositoryFactorySupport.java:412) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]
        at java.util.Optional.map(Optional.java:215) ~[na:1.8.0_101]
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:403) ~[spring-data-commons-2.0.0.BUILD-SNAPSHOT.jar:na]

代码:

产品 :

@Entity
@Table(name="PRODUCT")
public class Product implements Serializable {


    @Id
    @GeneratedValue
    @Column(name="PRODUCT_ID")
    private Long productId;

    @Column(name="PRODUCT_NAME")
    private String productName;



}

产品库

public interface ProductRepository extends ReactiveCrudRepository<Product, Long>{
}

pom.xml:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.BUILD-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

Github: Project Link

请建议这里的问题是什么以及如何解决它。

出现此错误是因为 ReactiveCrudRepository 不受 Spring Data JPA 支持。

根据这个Spring Data official blog bost (November 23, 2016),目前只支持MongoDB,Cassandra和Redis:

Support for reactive data access

The most significant additions that made it into the milestone is the addition of support for reactive data access for selected stores. This means: reactive Spring Data repositories and templates for MongoDB, Cassandra and Redis.

根据 Mark Paluch 在 jira.spring.io 上的评论,JPA 将不受支持。

We won't provide reactive support for Spring Data JPA. Exposing a reactive API creates the expectation of being reactive but that's the exact opposite for JPA. JPA is blocking, requires a transaction context, that is bound to a thread and the whole JDBC backend follows a blocking approach as well. Providing a reactive API for relational databases could still make sense in a context of reactive/asynchronous database drivers.

这是另一个相关的 Whosebug 问题:ReactiveCrudRepository to use Hibernate in spring