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。
问题:通过扩展 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。