Extending Spring Data CoroutineCrudRepository throws PropertyReferenceException

Viewed 991

In my project I've got a Kotlin (1.3.72) Spring Boot(2.3.3.RELEASE) JPA backed repository which works just fine, Spring application context starts up normally, project passes all tests, etc. etc.:

@Repository
interface MappingRepository : CrudRepository<RoutingMapping, Long> {
    fun findByCompanyId(companyId: Long): RoutingMapping?
}

when I switch it to extending org.springframework.data.repository.kotlin.CoroutineCrudRepository like so without changing anything else:

@Repository
interface MappingRepository : CoroutineCrudRepository<RoutingMapping, Long> {
    fun findByCompanyId(companyId: Long): RoutingMapping?
}

starting up the Spring application context fails on startup and throws the following:

Caused by: org.springframework.data.mapping.PropertyReferenceException:
No property count found for type RoutingMapping!`

This is a confusing exception since RoutingMapping is the mapped @Entity. I'm not clear on if I'm missing something on the @Entity side or if it's my misunderstanding of how to use org.springframework.data.repository.kotlin.CoroutineCrudRepository.


Caused by: org.springframework.data.mapping.PropertyReferenceException: No property count found for type RoutingMapping!
    at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:94)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:382)
    at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:358)
    at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:311)
    at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330)
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:293)
    at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:276)
    at org.springframework.data.repository.query.parser.Part.<init>(Part.java:82)
    at org.springframework.data.repository.query.parser.PartTree$OrPart.lambda$new$0(PartTree.java:251)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
    at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:252)
    at org.springframework.data.repository.query.parser.PartTree$Predicate.lambda$new$0(PartTree.java:381)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
    at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
    at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:382)
    at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:94)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:89)
    ... 137 more
1 Answers

count is one of the method that needs to be implemented when you are extending CoroutineCrudRepository. I guess you are also trying to return this interface in one of your implementation classes. So, if you add that, it will fail with other methods since it's an interface. Instead, to make this work, you can have one more interface which is being returned in your classes wherever you are trying to implement this interface. So, for e.g. I would have another interface called MappingMongoRepository which has abstract methods same as MappingRepository and use MappingMongoRepository being returned in my classes.

Related