spring-projects / spring-projects/spring-data-commons

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

Open
#2,941 0 comments 0 reactions 1 assignee View on GitHub

@schauder is already working on this.

Since Oct 2, 2023.

status: waiting-for-triage
Dominant language
Java
Stars
838
Forks
730
PR merge metrics
No merged PRs in 30d

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.