Skip to content

Projection is not allowed if filter criteria fields do not exist in the projection DTO kotlin data classes #2941

Open
@sunny-chung

Description

@sunny-chung

I have a Spring data repository like this:

interface ChatMessageRepository : BaseRepository<ChatMessage> {

    suspend fun findByChannelIdAndActive(
        channelId: String,
        active: Boolean
    ): List<ChatMessageResource>
}

@NoRepositoryBean
interface BaseRepository<T : BaseEntity> : CoroutineCrudRepository<T, String> {
    suspend fun findByActive(isActive: Boolean): List<T>

    suspend fun findByIdAndActive(id: String, isActive: Boolean): T?

    suspend fun countByIdAndActive(id: String, isActive: Boolean): Int
}

Classes like this:

@Table(name = "chat__message")
data class ChatMessage(
    val channelId: String,
    val senderId: String,
    val content: String
) : BaseEntity()

abstract class BaseEntity {
    @Id
    var id: String = UUID.randomUUID().toString()

    var isActive: Boolean = true

    @CreatedDate
    var createAt: Instant? = null
}

data class ChatMessageResource(
    val senderId: String,
    val content: String,
    val createAt: Instant
)

Exception would be thrown on Spring Boot startup:

2023-09-26T11:55:38.434+08:00 ERROR [,,] 1 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'messageApi': Unsatisfied dependency expressed through field 'chatMessageRepository': Error creating bean with name 'chatMessageRepository' defined in com.example.repository.ChatMessageRepository defined in @EnableR2dbcRepositories declared on R2dbcRepositoriesAutoConfigureRegistrar.EnableR2dbcRepositoriesConfiguration: Could not create query for public abstract java.lang.Object com.example.repository.ChatMessageRepository.findByChannelIdAndActive(java.lang.String,boolean,kotlin.coroutines.Continuation); Reason: Failed to create query for method public abstract java.lang.Object com.example.repository.ChatMessageRepository.findByChannelIdAndActive(java.lang.String,boolean,kotlin.coroutines.Continuation); No property 'channelId' found for type 'ChatMessageResource'
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:716) ~[spring-beans-6.0.11.jar!/:6.0.11]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:696) ~[spring-beans-6.0.11.jar!/:6.0.11]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:145) ~[spring-beans-6.0.11.jar!/:6.0.11]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:483) ~[spring-beans-6.0.11.jar!/:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1416) ~[spring-beans-6.0.11.jar!/:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:597) ~[spring-beans-6.0.11.jar!/:6.0.11]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.11.jar!/:6.0.11]

...

Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.lang.Object com.example.repository.ChatMessageRepository.findByChannelIdAndActive(java.lang.String,boolean,kotlin.coroutines.Continuation); No property 'channelId' found for type 'ChatMessageResource'
	at org.springframework.data.r2dbc.repository.query.PartTreeR2dbcQuery.<init>(PartTreeR2dbcQuery.java:74) ~[spring-data-r2dbc-3.1.2.jar!/:3.1.2]
	at org.springframework.data.r2dbc.repository.support.R2dbcRepositoryFactory$R2dbcQueryLookupStrategy.resolveQuery(R2dbcRepositoryFactory.java:179) ~[spring-data-r2dbc-3.1.2.jar!/:3.1.2]
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:111) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	... 50 common frames omitted
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property 'channelId' found for type 'ChatMessageResource'
	at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:90) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:405) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:381) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:334) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330) ~[na:na]
	at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:316) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:299) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.repository.query.parser.Part.<init>(Part.java:81) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.repository.query.parser.PartTree$OrPart.lambda$new$0(PartTree.java:242) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
	at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:243) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.repository.query.parser.PartTree$Predicate.lambda$new$0(PartTree.java:372) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
	at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
	at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:373) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:96) ~[spring-data-commons-3.1.2.jar!/:3.1.2]
	at org.springframework.data.r2dbc.repository.query.PartTreeR2dbcQuery.<init>(PartTreeR2dbcQuery.java:70) ~[spring-data-r2dbc-3.1.2.jar!/:3.1.2]
	... 52 common frames omitted

If I do not use projection, the application is working fine.

Please let me know if anything I could help.

Versions:
Kotlin 1.8.22
JVM Target 17
Spring Data Commons 3.1.2
Spring Data R2dbc 3.1.2

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions