The best way to predict the future is to create it.

How findByIDAndNameOrderBy xx is resolved in Micronaut


If you check the source of micronaunt


You’ll find the key logic is in findInterceptor, which will map the operation to an interceptor

private @NonNull
DataInterceptor<Object, Object> findInterceptor(
@Nullable String dataSourceName,
@NonNull Class<?> operationsType,
            @NonNull Class<?> interceptorType) {
DataInterceptor interceptor;

The interceptor could be

  • FindOneInterceptor

  • public class DefaultFindOneInterceptor

  • public interface FindAllInterceptor<T, R> extends IterableResultInterceptor<T, R> {
  • public class DefaultFindAllInterceptor<


Within following source code, io/micronaut/data/runtime/intercept/ You may find following useful logic:

public Object intercept(RepositoryMethodKey methodKey, MethodInvocationContext<T, Object> context) {
PreparedQuery<?, ?> preparedQuery = prepareQuery(methodKey, context, null);
return convertOne(

The operation is one HibernateJpaOperations

While in ApplicantChangesRepository

@Repositorypublic interface ApplicantChangesRepository extends JpaRepository<ApplicantChange, Integer> {

Following method

Optional<ApplicantChange> findFirstOrderByChangeIdDesc();

Due to cache of Hibernate, the first call to applicantChangesRepository.findFirstOrderByChangeIdDesc() will actually load ALL records into cache, then the 2nd call applicantChangesRepository.findFirstOrderByChangeIdDesc() would NO need database query.

even find first record, it still load ALL RECORDS. I think this is one bug in Micronaunt JAP implementation