Skip to content

A custom annotation above the method to generate SQL by the name of the method #1864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
KirillKurdyukov opened this issue Aug 23, 2024 · 5 comments
Labels
for: stackoverflow A question that's better suited to stackoverflow.com

Comments

@KirillKurdyukov
Copy link

KirillKurdyukov commented Aug 23, 2024

I'm trying to make an annotation that will participate in SQL generation on a spring-data-jdbc. You can say this is a hint for using an index in a database. It can look like:

@UseIndex("name_index")
findByName(String name)

I found a way to implement an interceptor from JdbcRepositoryFactoryBean:

    class UseIndexInterceptor : MethodInterceptor {

        override fun invoke(invocation: MethodInvocation): Any? {
            val useIndex = invocation.method.getAnnotation(UseIndex::class.java)
            threadBoundUseIndex.set(useIndex)
            try {
                return invocation.proceed()
            } finally {
                threadBoundUseIndex.remove()
            }
        }
    }

And use it in MySelectRenderContext

And the question is, is it possible to do something better?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 23, 2024
@mp911de
Copy link
Member

mp911de commented Aug 23, 2024

Methods invoked on the repository interface are already exposed in a thread-bound arrangement through ExposeInvocationInterceptor. You can obtain the currently invoked method by calling ExposeInvocationInterceptor.currentInvocation().

@mp911de mp911de added the status: waiting-for-feedback We need additional information before we can continue label Aug 23, 2024
@KirillKurdyukov
Copy link
Author

Thank you very much, Mark! I will use this static method in my dialect now!
If I understood correctly:

    @Override
    protected Function<Select, CharSequence> getAfterFromTable() {
        return select -> {
            var tables = select.getFrom().getTables();
            if (tables.size() != 1) {
                return "";
            }

            var viewIndex = ExposeInvocationInterceptor.currentInvocation().getMethod().getAnnotation(ViewIndex.class);
            
            var tableName = tables.get(0).getReferenceName();

            return viewIndex != null ?
                    "VIEW " + viewIndex.name() + " AS " + tableName : "";
        };
    }

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Aug 23, 2024
@mp911de mp911de added for: stackoverflow A question that's better suited to stackoverflow.com and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided labels Aug 23, 2024
@mp911de mp911de closed this as completed Aug 23, 2024
@KirillKurdyukov
Copy link
Author

KirillKurdyukov commented Feb 13, 2025

Spring version: 3.4.2 :(
(For 3.2.1 it is working)

java.lang.IllegalStateException: No MethodInvocation found: Check that an AOP invocation is in progress and that the ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, note that advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor! In addition, ExposeInvocationInterceptor and ExposeInvocationInterceptor.currentInvocation() must be invoked from the same thread.

@KirillKurdyukov
Copy link
Author

Hi @mp911de,

Could you please help me ? Any advice would be much appreciated!

@mp911de
Copy link
Member

mp911de commented Feb 13, 2025

With spring-projects/spring-data-commons#3090 (Spring Data 3.4) we disabled default metadata exposure to be less resource-intensive. You can enable exposing invocation metadata by setting RepositoryFactoryBeanSupport.setExposeMetadata(true), ideally through a BeanPostProcessor.postProcessBeforeInitialization(…).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: stackoverflow A question that's better suited to stackoverflow.com
Projects
None yet
Development

No branches or pull requests

3 participants