Description
Environment:
Kotlin with coroutines 2.1.0
Spring Boot 3.3.1
Problem
When adding a @meta annotation to my queries in a given repository, I get empty lists as result.
Unfortunately, I could not find the root cause yet, but I hope the following description helps to reproduce it.
CrudMethodMetadataPopulatingMethodInterceptor checks if a method is a query using isQueryMethod()
. Because @meta adds @QueryAnnotation, the method is not added to Set<Method> implementations
.
Surprisingly, query methods defined in repositories by default are added to Set<Method> implementations
from CrudMethodMetadataPopulatingMethodInterceptor, and everything works fine when not adding the @meta annotation.
The difference I see so far is in the execution path for the query in the following method:
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
if (!implementations.contains(method)) {
return invocation.proceed();
}
MethodInvocation oldInvocation = currentInvocation.get();
currentInvocation.set(invocation);
try {
CrudMethodMetadata metadata = (CrudMethodMetadata) TransactionSynchronizationManager.getResource(method);
if (metadata != null) {
return invocation.proceed();
}
CrudMethodMetadata methodMetadata = metadataCache.get(method);
if (methodMetadata == null) {
methodMetadata = new DefaultCrudMethodMetadata(repositoryInformation.getRepositoryInterface(), method);
CrudMethodMetadata tmp = metadataCache.putIfAbsent(method, methodMetadata);
if (tmp != null) {
methodMetadata = tmp;
}
}
TransactionSynchronizationManager.bindResource(method, methodMetadata);
try {
return invocation.proceed();
} finally {
TransactionSynchronizationManager.unbindResource(method);
}
} finally {
currentInvocation.set(oldInvocation);
}
}
}
When adding @meta annotation, my query is executed through invocation.proceed()
within if (!implementations.contains(method))
block. If @meta is not present, the execution is done by the rest of the code.
Repository example:
interface MyRepository : ReactiveMongoRepository<MyDocument, MyKey> {
@Meta(maxExecutionTimeMs = 30000)
override fun findAllById(ids: Iterable<MyKey>): Flux<MyDocument>
@Meta(maxExecutionTimeMs = 30000)
override fun findById(id: MyKey): Mono<MyDocument>
}
I'll update the issue if I have more information.
By the way, all I want in this case is to define maxExecutionTimeMs for my queries and I believe there should be a better way to customise it (and specially set a default) without having to define it for each method in the repository. Like having an interceptor for easily extending the Query options, for example.
Thank you for looking into it.